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

React Router 6刷新页面后如何保留在受保护路由?

解决React Router 6刷新受保护路由跳转首页的问题

问题根源

刷新页面后Redux状态重置,loadUser异步请求完成前,isAuthenticated处于未认证状态,同时路由结构不符合React Router 6规范,导致页面错误跳转。

解决方案

1. 修复路由结构(必须用<Routes>包裹)

React Router 6要求所有<Route>必须放在<Routes>组件内部,否则路由匹配会异常。修改App.js:

import { Routes, Route } from 'react-router-dom';
// 导入Login等组件

export default function App() {
  useEffect(() => {
    store.dispatch(loadUser())
  }, [])

  return (
    <Routes>
      <Route path="/" element={<Home />} />
      <Route element={<Protected />}>
        <Route path="profile" element={<Profile />} />
      </Route>
      <Route path="/login" element={<Login />} />
    </Routes>
  )
}

2. 优化Protected路由,避免加载时跳转

在loadUser请求过程中,加入加载状态判断,不要直接跳转,等请求完成后再做认证判断:

import { useSelector } from 'react-redux'
import { Navigate, Outlet } from 'react-router-dom'

const Protected = () => {
    const { isAuthenticated, loading } = useSelector(state => state.auth)
    
    // 加载中时显示加载组件,避免过早跳转
    if (loading) {
        return <div>加载中...</div>; // 替换成你的自定义加载组件
    }

    return isAuthenticated ? <Outlet /> : <Navigate to='/login' replace />;
}
export default Protected

3. 修正authReducer初始状态

确保初始状态包含loading和isAuthenticated字段,避免undefined导致的逻辑错误:

export const authReducer = (state = { 
    user: {}, 
    isAuthenticated: false, 
    loading: false 
}, action) => {
    switch (action.type) {
        case LOGIN_REQ:
        case REGISTER_REQ:
        case LOAD_USER_REQ:
            return {
                ...state, // 保留原有状态,避免覆盖user等字段
                isAuthenticated: false,
                loading: true
            }
        // ... 其他case保持不变
        default:
            return state
    }
}

4. 确保请求携带认证Token

刷新页面时,axios请求需要自动携带登录时存储的Token,否则/api/profile会返回401。在全局配置axios拦截器:

// 在userActions.js或单独的axios配置文件中
import axios from 'axios';

axios.interceptors.request.use(
    config => {
        // 假设登录成功后将Token存在localStorage
        const token = localStorage.getItem('token');
        if (token) {
            config.headers.Authorization = `Bearer ${token}`;
        }
        return config;
    },
    error => Promise.reject(error)
);

完成以上步骤后,刷新profile页面时,会先显示加载状态,等loadUser请求成功并更新Redux状态后,自动渲染Profile组件,不会跳转到首页。

内容的提问来源于stack exchange,提问作者5fingered sloth

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 21:56:00