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

在NextJS中使用Next-Auth时页面无限重渲染问题求助

问题描述

使用NextAuth实现Google登录时,页面出现无限重渲染,控制台能打印出用户session对象,但页面始终显示「Sign In」按钮,无法切换到「Sign Out」状态。

现有代码

1. /app/api/auth/[...nextauth]/route.js

import NextAuth from "next-auth/next";
import GoogleProvider from "next-auth/providers/google";

export const authOptions = {
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_CLIENT_ID,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET,
    }),
  ],
};

const handler = NextAuth(authOptions);
export { handler as GET, handler as POST };

2. sessionProvider.js

"use client";

import React from "react";
import { SessionProvider } from "next-auth/react";

const Sessionprovider = ({ children }) => {
  return <SessionProvider>{children}</SessionProvider>;
};

export default Sessionprovider;

3. Layout.js

<html lang="en">
      <body className={inter.className}>
        <Sessionprovider>{children}</Sessionprovider>
      </body>
    </html>

4. page.js

"use client";
import { getServerSession } from "next-auth";
import { signIn, signOut, useSession } from "next-auth/react";
import { authOptions } from "./api/auth/[...nextauth]/route";

export default async function Home() {
  const { data: session, status } = useSession();
  console.log(session);

  const _signInWithGoogle = async () => {
   await signIn("google");
  };

  return (
    <div className="flex justify-center items-center flex-col gap-3 p-5">
      <h1 className="font-semibold text-lg">Home Page</h1>
      {session ? (
        <button
          onClick={() => signOut()}
          className="p-1 bg-blue-400 text-white font-semibold rounded-md hover:bg-blue-500"
        >
          Sign Out
        </button>
      ) : (
        <button
          onClick={_signInWithGoogle}
          className="p-1 bg-blue-400 text-white font-semibold rounded-md hover:bg-blue-500"
        >
          Sign In
        </button>
      )}
    </div>
  );
}

问题原因

  1. 客户端组件误用异步函数:标记了"use client"的组件不能是async function,React会将此类组件判定为不稳定,引发无限重渲染。
  2. 不必要的服务端API引入:客户端组件中不需要getServerSession(这是服务端专用API),引入后会触发额外渲染逻辑,加重问题。
  3. 组件命名不一致(潜在隐患):自定义的Session组件命名为Sessionprovider(小写p),与NextAuth官方组件名SessionProvider混淆,可能导致状态传递异常。

修复方案

1. 修正page.js

移除async关键字和服务端API相关代码,客户端仅保留useSession:

"use client";
import { signIn, signOut, useSession } from "next-auth/react";

export default function Home() {
  const { data: session, status } = useSession();
  console.log(session);

  const _signInWithGoogle = () => {
    signIn("google");
  };

  return (
    <div className="flex justify-center items-center flex-col gap-3 p-5">
      <h1 className="font-semibold text-lg">Home Page</h1>
      {session ? (
        <button
          onClick={() => signOut()}
          className="p-1 bg-blue-400 text-white font-semibold rounded-md hover:bg-blue-500"
        >
          Sign Out
        </button>
      ) : (
        <button
          onClick={_signInWithGoogle}
          className="p-1 bg-blue-400 text-white font-semibold rounded-md hover:bg-blue-500"
        >
          Sign In
        </button>
      )}
    </div>
  );
}

2. 统一Session组件命名(可选但推荐)

修改sessionProvider.js的组件名,与官方保持一致:

"use client";

import React from "react";
import { SessionProvider } from "next-auth/react";

const SessionProvider = ({ children }) => {
  return <SessionProvider>{children}</SessionProvider>;
};

export default SessionProvider;

同步更新Layout.js中的引用:

<html lang="en">
  <body className={inter.className}>
    <SessionProvider>{children}</SessionProvider>
  </body>
</html>

验证修复

重启应用后,页面将停止无限重渲染,且能根据session状态正确切换「Sign In」/「Sign Out」按钮。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 23:22:40