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

NextJS中useRouter的router.push()无响应问题求助

问题分析与解决方案

你遇到的问题核心是登录成功后直接调用router.push('/')未触发预期跳转,但通过useEffect监听userId变化后调用却生效,这本质是Next.js客户端导航与状态同步的时机问题,以下是具体原因和解决办法:

核心原因

  1. 登录状态未及时同步
    调用signIn.attemptFirstFactor成功后,userId等登录状态可能还未完成更新(比如状态管理库、全局上下文的状态同步存在延迟)。此时直接执行router.push('/'),首页的权限校验组件可能读取到的还是旧的未登录状态,会自动重定向回登录页,看起来像是push没生效,但实际是跳转后又被拦截回原页面。

  2. 客户端导航的特性限制
    router.push是Next.js的客户端导航,不会刷新页面。如果首页组件依赖的登录状态没有触发重新渲染,页面会保持旧状态,导致你误以为跳转未执行。而router.reload()会强制刷新页面,此时所有状态会重新初始化,自然能读取到最新的登录状态。

解决方案

方案1:等待登录状态同步后再跳转

不要在authHandler中直接调用router.push,而是通过useEffect监听登录状态的变化(比如userId或专门的登录状态标识),确保状态更新完成后再触发跳转:

// 保留你的authHandler逻辑,移除里面的router.push
const authHandler = useCallback(async (emailCode) => {
  setIsLoading(true);
  try {
    await signIn.attemptFirstFactor({
      strategy: 'email_code',
      code: emailCode,
    });
    createAlerts('Success', false);
  } catch (error) {
    handleForeignAlert(error, 'Code is incorrect or expired');
  } finally {
    setIsLoading(false);
  }
}, [signIn, createAlerts, handleForeignAlert]);

// 监听userId变化触发跳转
useEffect(() => {
  if (userId) {
    router.push('/');
  }
}, [userId, router]);

方案2:强制跳转时刷新页面(临时应急方案)

如果需要在authHandler中直接跳转,可以给router.push添加forceRefresh参数,强制刷新页面以确保状态同步:

router.push('/', undefined, { forceRefresh: true });

注意:这种方式会放弃客户端导航的优势,不推荐作为长期方案,仅用于临时调试或特殊场景。

方案3:检查首页的权限拦截逻辑

排查首页组件中是否存在权限校验代码(比如路由守卫、高阶组件),确保校验逻辑能实时响应登录状态的变化。比如如果使用了useSWR或react-query获取用户信息,需要确保数据已完成更新再进行权限判断。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 08:50:42