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

NextAuth授权后useState未更新,仅页面刷新后显示会话数据

解决NextAuth登录后Context用户状态不实时更新的问题

问题分析

你的代码存在两个核心问题,导致登录后用户状态为null,必须刷新页面才会显示:

  1. 服务器端初始值无法同步客户端会话更新:RootLayout中通过getServerSession获取的会话仅在页面首次渲染时生效,登录后客户端的会话更新不会自动同步到UserProvider的user props。
  2. 登录逻辑错误更新状态:loginUser函数中调用signIn后,直接使用初始传入的user props(登录前为null)更新状态,并没有获取登录后的最新会话数据。

解决方案

通过结合NextAuth客户端钩子useSession监听会话变化,实现用户状态的实时同步:

1. 修改UserProvider.ts代码

'use client'

import { useSession, signIn } from "next-auth/react"
import React, { useEffect } from "react"
import { useRouter } from "next/navigation"

type LoginProps = {
  email: string
  password: string
}

type UserProviderProps = {
  user: IUser | null
  loginUser: (login: LoginProps) => Promise<void>
  setUser: React.Dispatch<React.SetStateAction<IUser | null>>
}

const UserContext = React.createContext<UserProviderProps>({} as UserProviderProps)

export const UserProvider: React.FC<{
  children: React.ReactNode
}> = ({ children }) => {
  const router = useRouter()
  // 使用NextAuth客户端钩子获取实时会话
  const { data: session, status } = useSession()
  const [current_user, setUser] = React.useState<IUser | null>(session?.user || null)

  // 监听会话变化,自动更新用户状态
  useEffect(() => {
    if (session?.user) {
      setUser({ ...session.user })
    } else {
      setUser(null)
    }
  }, [session])

  async function loginUser(login: LoginProps) {
    const result = await signIn('credentials', { ...login, redirect: false })
    // 登录成功后无需手动setUser,useSession会自动监听会话变化更新状态
    if (result?.ok) {
      // 可选:登录成功后跳转页面
      // router.push('/dashboard')
    }
  }

  const value = React.useMemo(() => {
    return {
      user: current_user,
      loginUser,
      setUser,
    }
  }, [current_user])

  return <UserContext.Provider value={value}>{children}</UserContext.Provider>
}

export const useUser = () => React.useContext(UserContext)

2. 简化layout.ts代码

由于UserProvider现在会通过useSession自动获取客户端会话,不再需要从服务器端传递user props:

export default async function RootLayout({children}: {children: React.ReactNode}) {
  // 服务器端会话仍可保留,用于页面初始渲染的权限判断等场景
  const session: Session | null = await getServerSession(authOptions)

  return (
    <html>
      <body>
        <AuthProvider>
          <UserProvider>
            <Providers>
               {children}
            </Providers>
          </UserProvider>
        </AuthProvider>
      </body>
    </html>
  )
}

关键改动说明

  • 引入useSession钩子:实时监听客户端会话变化,替代仅依赖服务器端初始值的逻辑。
  • 添加useEffect监听会话:当会话更新(如登录、登出)时,自动同步current_user状态。
  • 修正登录逻辑:登录成功后不再手动设置旧的user值,而是依赖useSession的自动更新机制。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 05:07:07