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

Next.js调用router.push跳转后Nav组件useEffect不触发的解决方法

问题原因

你遇到的是Next.js共享布局的正常特性:登录页和首页都复用同一个Layout组件,放在Layout里的Nav组件在客户端路由跳转(router.push)过程中不会被卸载重挂载,你给useEffect设置的是空依赖数组,只会在Nav组件首次挂载时执行一次,后续跳转自然不会触发。
而window.location.replace是整页重载,整个React应用会重新初始化,Nav组件也会重新挂载,所以useEffect会执行。

解决方案

这里提供两种常见的修复方案,按需选择即可:


方案1:监听路由变化触发状态更新

直接把路由路径作为useEffect的依赖项,每次路由跳转都会重新读取本地存储的用户信息,改造成本极低,适合小型项目。
修改Nav.jsx中的useEffect代码:

// 已经引入了useRouter,直接把router.pathname加入依赖数组
useEffect(() => {
    console.log('hi');
    const storedUser = JSON.parse(localStorage.getItem('user'));
    if (storedUser) setUser(storedUser);
}, [router.pathname]);

方案2:监听自定义登录状态事件(更高效)

如果不想每次路由跳转都执行冗余逻辑,可以在登录/登出操作时触发自定义事件,Nav组件监听事件更新状态,性能更好:

  1. 首先修改login.jsx,存储完用户信息后触发事件:
axios.post(`/auth/login`, loginForm).then((res) => {
    const {data, token} = res.data;
    localStorage.setItem('auth_token', token);
    localStorage.setItem('user', JSON.stringify(data));
    // 触发登录状态变化事件
    window.dispatchEvent(new Event('authStateChange'));
    router.push('/');
})
  1. 再修改Nav.jsx的useEffect,监听事件更新状态:
useEffect(() => {
    const updateUserInfo = () => {
        console.log('hi');
        const storedUser = JSON.parse(localStorage.getItem('user'));
        setUser(storedUser || null);
    };
    // 组件首次挂载时执行一次
    updateUserInfo();
    // 监听登录状态变化事件
    window.addEventListener('authStateChange', updateUserInfo);
    // 组件卸载时清理事件监听
    return () => window.removeEventListener('authStateChange', updateUserInfo);
}, []);

后续登出操作清完本地存储后,也可以触发同一个authStateChange事件,Nav会自动更新为未登录状态,不需要调用router.reload()刷新页面。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 19:36:04