React+Redux项目登出时出现Cannot read properties of null (reading 'token')错误求助
MERN Goal Setter 登出时Redux重置问题解决方案
核心问题原因
登出时auth.user被置为null,但Dashboard组件的useEffect会因user状态变化重新触发,里面调用的getGoals异步Thunk会尝试读取auth.user.token,此时user已为null,直接抛出Cannot read properties of null (reading 'token')错误。同时启用组件卸载时的reset()会触发goals状态反复变化,加剧循环触发导致Chrome卡顿。
分步解决办法
1. 给异步Thunk添加安全校验
修改goalSlice.js中的createGoal和getGoals,先判断用户是否存在再读取token,避免空指针错误:
// 创建新目标 export const createGoal = createAsyncThunk('goals/create', async (goalData, thunkAPI) => { try { const user = thunkAPI.getState().auth.user if (!user) { return thunkAPI.rejectWithValue('用户未登录') } const token = user.token return await goalService.createGoal(goalData, token) } catch (error) { const message = (error.response && error.response.data && error.response.data.message) || error.message || error.toString() return thunkAPI.rejectWithValue(message) } } ) // 获取用户目标 export const getGoals = createAsyncThunk('goals/getAll', async(_, thunkAPI) => { try { const user = thunkAPI.getState().auth.user if (!user) { return thunkAPI.rejectWithValue('用户未登录') } const token = user.token return await goalService.getGoals(token) } catch (error) { const message = (error.response && error.response.data && error.response.data.message) || error.message || error.toString() return thunkAPI.rejectWithValue(message) } })
2. 优化Dashboard的useEffect逻辑
仅当用户存在时才调用getGoals,避免无意义的请求触发:
useEffect(() => { if(isError){ console.log("iserror "+ message) } if(!user){ navigate('/login') return // 用户未登录时直接跳转,不执行后续逻辑 } dispatch(getGoals()) // 移除组件卸载时的reset,统一在登出流程中处理 } , [user, navigate, isError, message, dispatch] )
3. 在登出流程中统一重置Goals
在触发登出的组件(比如导航栏的登出按钮)中,等登出异步操作完成后再重置goals状态,确保状态清理时机正确:
// 示例:登出按钮的点击事件处理 import { useDispatch, useNavigate } from 'react-redux' import { logout } from '../features/auth/authSlice' import { reset } from '../features/goals/goalSlice' const handleLogout = () => { const dispatch = useDispatch() const navigate = useNavigate() dispatch(logout()).then(() => { dispatch(reset()) // 登出完成后再重置目标状态 navigate('/login') }) }
内容的提问来源于stack exchange,提问作者Anish Dalvi
相关产品推荐
相关产品推荐

