React Redux页面刷新后状态异常 已登录用户无法直接访问受保护路由
问题根因
- 页面刷新后Redux状态重置为初始值,此时
isLoading默认值为false、isAuthenticated默认值为null,!isAuthenticated判断结果为真,PrivateRoute直接触发重定向到登录页,此时校验token有效性的load_user请求还未返回结果,没有机会更新登录状态。 - 站内点击导航栏跳转属于单页应用内部路由切换,Redux状态不会丢失,
isAuthenticated已经是true,所以可以正常访问。
解决方案
1. 修改auth reducer初始状态
将isLoading初始值改为true,页面初始化时默认处于身份校验加载状态:
const initialState = { access: localStorage.getItem('access'), refresh: localStorage.getItem('refresh'), isAuthenticated: null, isLoading : true, // 此处从false修改为true user: null, requestSent: false, payload: null, message: null }
2. 完善reducer中isLoading的状态更新逻辑
在身份校验的各个结果分支中,都更新isLoading为false,结束加载状态:
switch(type){ case AUTHENTICATED_SUCCESS: return { ...state, isAuthenticated: true, isLoading: false // 新增 } case LOGIN_SUCCESS: localStorage.setItem('access', payload.access); return{ ...state, isAuthenticated: true, access: payload.access, refresh: payload.refresh, isLoading: false // 新增 } // 新增身份校验失败、登录失败、登出的状态处理 case AUTHENTICATED_FAIL: case LOGIN_FAIL: case LOGOUT_SUCCESS: return { ...state, isAuthenticated: false, access: null, refresh: null, user: null, isLoading: false } }
3. 应用初始化时主动触发身份校验
在根组件App.js挂载时就调用load_user方法,校验本地存储的token有效性,不要等到路由跳转才执行校验:
// 函数组件示例 import { useEffect } from 'react' import { useDispatch } from 'react-redux' import { load_user } from './actions/auth' function App() { const dispatch = useDispatch() useEffect(() => { dispatch(load_user()) }, [dispatch]) // 原有路由渲染逻辑 return ( <div className="App"> {/* 原有路由代码 */} </div> ) }
修改后页面刷新时会先显示LOADING提示,等token校验完成后再判断是否跳转,符合预期逻辑。
内容的提问来源于stack exchange,提问作者StuckyBoy
相关产品推荐
相关产品推荐

