React应用加载时如何仅触发一次Redux action且刷新后不再重复执行?
实现方案
核心逻辑依赖浏览器本地持久化存储标记是否已经完成过首次权限申请流程,只要标记存在就跳过触发逻辑,刷新页面不会清空标记,完全匹配需求。
具体实现步骤
步骤1:修改应用初始化逻辑(index.js文件)
先校验本地标记再决定是否执行dispatch:
import { requestLocationPermission } from './actions'; import store from './store'; const init = () => { // 读取本地持久化标记,判断是否已经完成过首次权限申请 const hasRequestedLocation = localStorage.getItem('has_requested_location'); // 仅标记不存在时触发权限申请 if (!hasRequestedLocation) { store.dispatch(requestLocationPermission()); } // 其余应用初始化逻辑 ReactDOM.createRoot(document.getElementById('root')).render(<App />); }; init();
步骤2:修改action逻辑,权限交互完成后写入永久标记
无论用户同意、拒绝权限,或是浏览器不支持位置服务,只要权限弹窗交互结束就写入标记,避免后续重复触发:
// actions文件内的位置权限申请逻辑 export const requestLocationPermission = () => async (dispatch) => { // 浏览器不支持位置服务的场景 if (!navigator.geolocation) { dispatch({ type: 'LOCATION_NOT_SUPPORTED' }); localStorage.setItem('has_requested_location', 'true'); return; } navigator.geolocation.getCurrentPosition( // 用户同意授权的回调 (position) => { dispatch({ type: 'LOCATION_FETCH_SUCCESS', payload: { lat: position.coords.latitude, lng: position.coords.longitude } }); // 写入标记,后续不再触发 localStorage.setItem('has_requested_location', 'true'); }, // 用户拒绝授权/定位超时的回调 (error) => { dispatch({ type: 'LOCATION_FETCH_FAIL', payload: error.message }); // 即使用户拒绝也要写入标记,后续不再触发 localStorage.setItem('has_requested_location', 'true'); } ); };
补充说明
- 如果产品需要支持用户主动重新触发定位权限申请,可以单独做功能入口,调用该action前跳过localStorage校验即可
- 若项目已接入redux-persist等redux持久化方案,也可以将标记存储在redux持久化数据中,逻辑和localStorage实现完全一致
- 用户清空浏览器缓存、使用无痕模式访问时,会重新触发首次申请逻辑,属于符合用户预期的正常行为
内容的提问来源于stack exchange,提问作者lohith
相关产品推荐
相关产品推荐

