React页面刷新时Auth Reducer状态重置为null的问题及修复方案失效排查
问题排查与修复方案
我来帮你梳理下问题的核心原因,你遇到的情况是几个细节没对应上导致的,咱们一步步来修正:
1. Action 与 Reducer 的字段不匹配(核心问题)
你新增的 setCurrentUser Action 里,dispatch 的参数是 payload: data,但 Reducer 的 SET_USER 分支里却在读取 action.data——这就导致数据根本没被正确写入到 state 里,自然刷新后状态无法恢复,甚至可能干扰正常登录的状态更新。
修正后的 setCurrentUser Action:
// 注意:这里不需要 async,因为没有异步操作 export const setCurrentUser = (data) => (dispatch) => { try { console.log("ssssssssss"); dispatch({ type: SET_USER, data }); // 把 payload 改成 data,和 reducer 对应 } catch (error) { console.log(error); } }
2. 确保 SET_USER 类型常量正确定义与导入
要先确认 SET_USER 已经在你的 actionTypes 常量文件里定义,并且在 Action 文件中正确导入:
// constants/actionTypes.js export const AUTH = 'AUTH'; export const LOGOUT = 'LOGOUT'; export const SET_USER = 'SET_USER'; // 务必添加这一行
// 在你的 action 文件顶部 import { AUTH, LOGOUT, SET_USER } from '../constants/actionTypes'; // 导入 SET_USER
3. 修正 useEffect 的依赖逻辑
你当前把 location 作为 useEffect 的依赖,会导致每次路由变化都触发 dispatch,这不仅没必要,还可能在未登录时重复写入 null 覆盖状态。我们只需要在组件首次挂载时读取 localStorage 恢复状态即可:
修正后的 App 组件 useEffect:
React.useEffect(() => { const localUserData = JSON.parse(localStorage.getItem('profile')); // 加个判断,避免 localStorage 为空时写入 null if (localUserData) { dispatch(setCurrentUser(localUserData)); } console.log(JSON.parse(localStorage.getItem('profile'))); }, [dispatch]) // 依赖改为 dispatch(React 中 dispatch 是稳定引用)
4. 优化登出逻辑(可选)
你的 signout Action 里重复执行了 localStorage.clear(),而 Reducer 的 LOGOUT 分支已经做了这个操作,去掉重复代码更简洁:
export const signout = (router) => async(dispatch) => { try { dispatch({ type: LOGOUT }); // 移除这行:localStorage.clear() router.push('/'); } catch (error) { console.log(error); } }
修复后的流程验证
- 登录时:
AUTHAction 会把用户数据存入 localStorage 和 auth state,页面能正常获取用户信息 - 刷新页面:组件挂载时,useEffect 读取 localStorage 中的数据,通过
SET_USERAction 恢复 auth state - 登出时:
LOGOUTAction 清空 localStorage 和 auth state,页面回到未登录状态
内容的提问来源于stack exchange,提问作者Saurabh
相关产品推荐
相关产品推荐

