如何在Next.js 13+中使用notistack且无需将布局文件设为客户端组件
Next.js 13+ 集成 Notistack 且不标记根 Layout 为 Client Component 的方案
核心问题原因
Notistack 的 SnackbarProvider 依赖 React Context 实现状态管理,而 React Context 的创建与使用只能在客户端组件中进行。Next.js 13+ 的根 Layout 默认是服务器组件,直接在其中使用 SnackbarProvider 会触发 createContext only works in Client Components 错误。
解决方案
将 SnackbarProvider 封装为独立的客户端组件,再在根 Layout 中引入该组件即可,无需把根 Layout 标记为客户端组件。
步骤1:创建独立的 Notistack 客户端 Provider
在 app/providers/ 目录下新建 NotistackProvider.tsx 文件,内容如下:
'use client'; import { SnackbarProvider } from 'notistack'; export default function NotistackProvider({ children, }: { children: React.ReactNode; }) { // 可在此自定义 SnackbarProvider 的配置,比如位置、超时时间等 return <SnackbarProvider>{children}</SnackbarProvider>; }
步骤2:在根 Layout 中引入该 Provider
修改 app/layout.tsx,用上面创建的 NotistackProvider 包裹子组件,根 Layout 保持服务器组件属性:
import NotistackProvider from './providers/NotistackProvider'; export default function RootLayout({ children, }: { children: React.ReactNode; }) { return ( <html lang="zh-CN"> <body> <NotistackProvider>{children}</NotistackProvider> </body> </html> ); }
步骤3:在客户端组件中使用 Notistack
所有需要调用 useSnackbar 的组件必须是客户端组件(顶部添加 'use client' 指令),示例:
'use client'; import { useSnackbar } from 'notistack'; export default function NotificationButton() { const { enqueueSnackbar } = useSnackbar(); const showSuccessMsg = () => { enqueueSnackbar('操作完成!', { variant: 'success' }); }; return <button onClick={showSuccessMsg}>触发通知</button>; }
内容的提问来源于stack exchange,提问作者NJAS
相关产品推荐
相关产品推荐

