You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 07:40:31