升级Next.js 13.4后useSession需包裹SessionProvider报错排查
问题
将Next.js从13.0升级到13.4后,NextAuth功能异常。升级前在app目录根目录创建AuthProvider.js,用SessionProvider包裹子组件,再在根layout.js中用该AuthProvider包裹所有内容可正常运行,但升级后所有使用useSession的组件均抛出错误:Error: [next-auth]: useSession must be wrapped in a <SessionProvider />。当前使用next-auth版本为^4.18.8。
相关代码
AuthProvider.js
export function AuthProvider({ children }) { return ( <SessionProvider> <ChakraProvider> {/* <SkeletonTheme baseColor="#B3B3B3" highlightColor="#BCBCBC"> */} {children} {/* </SkeletonTheme> */} </ChakraProvider> </SessionProvider> ); }
app/layout.js
<html> <head /> <body className="max-w-7xl mx-auto"> <AuthProvider> <NextTopLoader color="#008080" showSpinner={false} /> {children} </AuthProvider> </body> </html>
原因分析
Next.js 13.4对App Router的组件渲染逻辑做了严格调整,核心是服务器组件与客户端组件的边界划分更清晰。13.0版本中根layout.js默认可兼容客户端组件上下文传递,但13.4版本后,App Router内组件默认是服务器组件,而SessionProvider、useSession都是客户端组件专属API,服务器组件无法传递客户端组件的上下文,导致子组件无法捕获SessionProvider的包裹,触发错误。
解决方法
1. 标记根layout为客户端组件
在app/layout.js顶部添加'use client'指令,将其转为客户端组件,确保SessionProvider的上下文能正确传递给所有子组件:
'use client'; import { AuthProvider } from './AuthProvider'; import NextTopLoader from 'nextjs-toploader'; export default function RootLayout({ children }) { return ( <html> <head /> <body className="max-w-7xl mx-auto"> <AuthProvider> <NextTopLoader color="#008080" showSpinner={false} /> {children} </AuthProvider> </body> </html> ); }
2. 明确AuthProvider的客户端组件身份
在AuthProvider.js顶部添加'use client'指令,避免组件身份模糊导致的上下文传递问题:
'use client'; import { SessionProvider } from 'next-auth/react'; import { ChakraProvider } from '@chakra-ui/react'; export function AuthProvider({ children }) { return ( <SessionProvider> <ChakraProvider> {/* <SkeletonTheme baseColor="#B3B3B3" highlightColor="#BCBCBC"> */} {children} {/* </SkeletonTheme> */} </ChakraProvider> </SessionProvider> ); }
3. 升级next-auth到兼容版本(可选)
当前使用的next-auth@4.18.8发布时间较早,对Next.js 13.4的App Router支持可能存在兼容性问题。可升级到最新4.x版本确保适配:
npm install next-auth@latest # 或 yarn add next-auth@latest
内容的提问来源于stack exchange,提问作者Mohammed Bekele

