React登录跳转Dashboard后需手动刷新才可加载数据问题咨询
问题根因
首次登录跳转Dashboard不触发接口请求、手动刷新后才正常加载的核心原因是Axios实例请求头初始化时机错误,同时存在一处useEffect使用隐患:
- 查看
axios.js代码可知,你在调用axios.create()创建实例时,直接同步执行getHeader()生成请求头,该逻辑仅会在Axios模块第一次被应用导入时执行一次:- 未登录状态下应用启动,模块初始化时localStorage内无token,生成的请求头不携带Authorization鉴权字段
- 登录成功后token被存入localStorage,但已经创建完成的Axios实例不会重新执行
getHeader()更新请求头,此时发起Dashboard数据请求时用的还是旧的无鉴权头配置,大概率会被前端路由鉴权或后端接口拦截,根本走不到请求成功的逻辑 - 手动刷新页面时整个应用重新加载,Axios模块重新初始化,此时localStorage内已经存在有效token,生成的请求头携带正确鉴权信息,请求可以正常发送
- 额外隐患:Dashboard页面的两个useEffect依赖数组为空,后续修改筛选条件时不会自动触发新的数据请求,且现有请求逻辑没有错误捕获,请求失败时无任何提示,会提升排查难度。
修复方案
1. 修复Axios动态请求头逻辑
不要在创建实例时写死headers配置,改用Axios请求拦截器,每次发送请求前实时从localStorage读取最新token生成请求头,修改后的axios.js代码如下:
import axios from 'axios'; import history from "../history"; const apiUrl = `https://test.mydomain.it/api/auth/`; const api = axios.create({ baseURL: apiUrl, }) // 请求拦截器:每次发请求前动态注入最新鉴权头 api.interceptors.request.use((config) => { const token = localStorage.getItem("token"); const expiration = localStorage.getItem("token_exp"); // token过期直接清理状态跳登录页 if (expiration * 1000 < Date.now()) { localStorage.removeItem("token"); localStorage.removeItem("token_exp"); history.push("/"); return Promise.reject("登录已过期"); } // 动态拼接请求头 config.headers = { "Content-Type": "application/json; charset=UTF-8", "Accept": 'application/json; charset=UTF-8', ...(token ? { Authorization: `Bearer ${token}`, useCredentials: true } : {}) } return config; }, (error) => { return Promise.reject(error); }) // 可选:添加响应拦截器统一处理未授权错误 api.interceptors.response.use((res) => res, (error) => { if (error.response?.status === 401) { localStorage.removeItem("token"); localStorage.removeItem("token_exp"); history.push("/"); } return Promise.reject(error); }) export default api;
2. 优化Dashboard页面数据请求逻辑
合并重复请求逻辑、补全依赖、添加错误捕获,支持筛选条件变化自动拉取新数据,修改后的请求相关代码如下:
const fetchDashboardData = async () => { try { if(dashboardfilter.year === "" && dashboardfilter.tributo === "" ){ const res = await getDashboard_Data(); setChart(res.data.data); }else{ // 此处补全带筛选参数的请求逻辑 } const res1 = await getDashboard_Data_byYear(dashboardfilter.year); setBarChart(res1.data.data); } catch (err) { console.error("加载仪表盘数据失败:", err); // 可在此处添加页面错误提示 } } useEffect(() => { fetchDashboardData(); // 依赖数组添加dashboardfilter,筛选条件变化时自动重新请求 }, [dashboardfilter]);
3. 校验登录跳转逻辑
确认getToken方法是在token成功写入localStorage之后才返回resolve,你现有登录代码中await getToken()执行完成后再判断token、执行跳转的逻辑没有问题,只要保证token写入操作是同步或被await等待即可。
验证排查步骤
修改完成后打开浏览器开发者工具的Network面板,登录跳转Dashboard时观察请求状态:
- 如果能看到接口请求,检查请求头是否携带Authorization字段,未携带则重新检查拦截器逻辑
- 如果请求正常发送但返回401状态码,检查localStorage内存储的token值是否正确、是否在有效期内
- 如果完全没有发出接口请求,检查路由鉴权逻辑是否在页面加载前就触发了重定向,同时查看Console面板是否有JavaScript报错
内容的提问来源于stack exchange,提问作者64Bit1990
相关产品推荐
相关产品推荐

