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

使用@reach/router的navigate跳转后Header组件未重新渲染如何解决?

问题根因分析
  • Header是全局挂载的公共组件,登录后调用navigate跳转仅路由发生变化,Header没有经历卸载-重挂载流程,原有useEffect不会重新触发拉取最新登录状态
  • 当前useEffect依赖设置为tokenObj,且在effect内部调用setToken更新tokenObj,会导致effect重复触发,存在死循环风险
  • 代码小问题:res.json(res)写法错误,json()方法不需要传入参数,且verify请求未加credentials: 'include',无法携带登录态cookie
修复方案

方案1:监听路由变化触发状态更新(适配现有逻辑,改动最小)

在Header中引入@reach/router提供的useLocation钩子,监听路由路径变化,每次路由跳转时重新拉取登录验证状态,同时清理错误的effect依赖即可。
修改后的header.js代码:

import { useLocation, Link } from '@reach/router'; // 新增路由相关导入

const Header = () => {
  const [tokenObj, setToken] = useState('');
  const location = useLocation(); // 获取当前路由信息
  
  useEffect(() => {
    fetch('/portfolio/verify', {
      method: "GET",
      credentials: 'include' // 新增配置,携带登录态cookie
    })
    .then((res)=>{
      if(res.ok) return res.json(); // 移除多余的res参数
    })
    .then((jsonRes)=> {
      setToken(jsonRes.token || '')
    });
  }, [location.pathname]); // 依赖改为路由路径,每次路由变化触发请求

  let lastNavLink;
  let lastNavHref;
  if(tokenObj){ 
    lastNavLink = 'Messages';
    lastNavHref = '/message'
  } else {
    lastNavLink = 'Login';
    lastNavHref = '/login';
  }
  // 替换原生a标签为Link组件,避免跳转时页面刷新
  return <Link to={lastNavHref}> {lastNavLink} </Link>
};

方案2:全局状态管理(性能更优,避免重复请求)

如果不想每次路由跳转都调用验证接口,可以用React Context/Redux等全局状态方案管理登录态:

  1. 定义全局AuthContext,存储token及登录状态更新方法
  2. 登录成功拿到accessToken后,直接更新Context中的token值
  3. Header组件直接从Context中取token判断展示内容,无需单独发起验证请求

内容的提问来源于stack exchange,提问作者PariParia

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 17:45:02