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

Next.js useRouter触发开发环境钩子渲染数量不一致错误排查

开发模式下Next.js App Router + next-auth登录后跳转触发"Rendered more hooks than during the previous render"错误

我正在基于Next.js App Router和next-auth搭建站点,客户端登录页面使用next-auth的凭证登录功能实现用户登录,登录成功后使用next/navigation的useRouter进行页面跳转。但在开发模式下触发**"Rendered more hooks than during the previous render"**错误,生产环境运行正常。错误在执行router.replace('/')时触发,以下是page.tsx代码:

'use client'
// all the imports
export default function LoginPage({}: Props) {
  const { data: session } = useSession()
  if (session) {
    redirect('/')
  }
  useEffect(() => {
    async function setP() {
      const res = await getProviders()
      setProviders(res)
    }
    setP()
  }, [])

  const [providers, setProviders] = useState<Record<
    LiteralUnion<BuiltInProviderType, string>,
    ClientSafeProvider
  > | null>(null)

  const email = useRef('')
  const password = useRef('')
  const {
    headingsContainer,
    mainContainer,
    register,
    loginBtnContainer,
    thirdPartyLoginContainer,
    forgetPass,
  } = styles
  const router = useRouter()

  async function handleSubmit(e: FormEvent<HTMLFormElement>) {
    e.preventDefault()
    const loginId = toast.loading('Checking your credentials...')
    const result = await signIn('credentials', {
      email: email.current,
      password: password.current,
      redirect: false,
    })
    if (result?.error) {
      toast.update(loginId, {
        render: 'Wrong Email or Password!...',
        type: 'error',
        isLoading: false,
        autoClose: 3000,
      })
    } else {
      toast.update(loginId, {
        render: '🦄 Logged In!',
        type: 'success',
        isLoading: false,
        autoClose: 3000,
      })
      router.replace('/') // <--- this causes the error
    }
  }
  return (
    <div className={mainContainer}>
      <form onSubmit={(e) => handleSubmit(e)}>
        <div className={headingsContainer}>
          <h3>Welcome Back</h3>
        </div>
        {/* <label htmlFor="email">Your Email</label> */}
        <input
          type="text"
          placeholder="Enter Email"
          name="email"
          onChange={(e) => {
            email.current = e.target.value
          }}
          required
        />

        <br />
        <br />

        {/* <label htmlFor="pswrd">Your password</label> */}
        <input
          type="password"
          placeholder="Enter Password"
          name="pswrd"
          onChange={(e) => {
            password.current = e.target.value
          }}
          required
        />
        <br />
        <br />
        <br />
        <div className={loginBtnContainer}>
          <button type="submit">Login</button>
        </div>
        <div>
          <p className={forgetPass}>
            <a href="#">Forgot Password?</a>
          </p>
        </div>
        <p className={register}>
          Not registered? <Link href="/auth/signup">Register here!</Link>
        </p>
      </form>

      <div className={thirdPartyLoginContainer}>
        {providers
          ? Object.values(providers).map((provider) =>
              provider.name !== 'Credentials' ? (
                <div key={provider.name}>
                  <button onClick={() => signIn(provider.id)}>
                    <Image
                      src={`https://authjs.dev/img/providers/${provider.id}-dark.svg`}
                      width={24}
                      height={24}
                      alt={`${provider.name} logo`}
                    />
                    Continue with {provider.name}
                  </button>
                </div>
              ) : null
            )
          : null}
      </div>
    </div>
  )
}

如需更多代码信息可告知。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 20:52:37