React/Redux获取用户地理位置并分发至Action Creator失败问题
你的代码核心问题在于**getLocation函数里的Promise没有正确等待地理位置获取完成**,导致后续的dispatch(getCoords(position))无法拿到有效的位置数据,甚至根本不会正确触发。
为什么原来的写法不生效?
navigator.geolocation.getCurrentPosition是基于回调的异步API,它不会返回Promise。你原来的写法用Promise.resolve()直接包裹它,会立即把getCurrentPosition的返回值(实际是undefined)作为Promise的resolve结果,而不会等待位置获取成功的回调(也就是showPosition)执行。这就导致loadNearbyShops里的.then()拿到的position是undefined,调用getCoords(position)时访问position.coords会直接报错,代码中断,自然你的action creator不会被正确触发。
修正后的代码
1. 正确包装getLocation的Promise逻辑
把getCurrentPosition的回调逻辑整合到Promise的resolve和reject中,确保只有当位置获取成功/失败时,Promise才会相应地完成:
function getLocation() { console.log("getLocation") return new Promise((resolve, reject) => { if (navigator.geolocation) { console.log("Boolean navigator.getLocation:" + Boolean(navigator.geolocation)) // 用getCurrentPosition的回调来控制Promise的状态 navigator.geolocation.getCurrentPosition( // 成功回调:获取到位置后resolve (position) => { console.log("showPosition"); resolve(position); }, // 失败回调:获取失败时reject (error) => { reject(`获取位置失败: ${error.message}`); } ); } else { reject("Geolocation is not supported by this browser.") } }) }
2. 确认Redux中间件配置
你的loadNearbyShops是一个返回函数的异步action creator,需要redux-thunk中间件支持才能被Redux正确处理。如果还没配置,需要在创建store时添加:
import { createStore, applyMiddleware } from 'redux'; import thunk from 'redux-thunk'; import yourRootReducer from './path-to-your-reducer'; const store = createStore( yourRootReducer, applyMiddleware(thunk) // 必须添加这一行 );
额外优化
你可以去掉单独的showPosition函数,直接把日志和resolve逻辑写在getCurrentPosition的成功回调里,让代码更简洁。
修正后再执行store.dispatch(loadNearbyShops()),就能正确触发getCoords action creator,把地理位置数据分发到Redux store里了。
内容的提问来源于stack exchange,提问作者devio

