Next.js中TypeError: createContext is not a function问题求助
错误根源
这个错误的核心原因是Next.js App Router默认的服务器组件(RSC)环境下,执行了仅支持客户端的React API。Radix UI的组件依赖React上下文(createContext),而createContext是客户端专属API,无法在服务器组件中运行。
从错误栈可以看到,问题始于@radix-ui/react-direction依赖,它在服务器编译阶段尝试调用createContext,而你的Navigation组件、navigation-menu.tsx等使用Radix UI的组件未标记为客户端组件,导致在服务器环境中被执行,触发了API不兼容错误。
解决步骤
1. 给使用Radix UI的组件添加'use client'指令
所有直接或间接使用Radix UI的组件,必须在文件最顶部添加'use client',告知Next.js这是客户端组件:
比如你的src/components/ui/navigation-menu.tsx:
'use client'; // 必须放在文件第一行 import * as React from 'react'; import * as NavigationMenuPrimitive from '@radix-ui/react-navigation-menu'; // 其他导入和组件代码...
同样,src/components/Navigation.tsx也需要添加:
'use client'; import { NavigationMenu } from './ui/navigation-menu'; // 其他代码...
2. 调整ClerkProvider的使用方式
ClerkProvider属于客户端组件,若你的layout.tsx是默认的服务器组件,建议单独创建客户端组件来包裹它,避免在服务器环境中执行客户端逻辑:
创建src/components/ClerkClientProvider.tsx:
'use client'; import { ClerkProvider } from '@clerk/nextjs'; export default function ClerkClientProvider({ children }: { children: React.ReactNode }) { return <ClerkProvider>{children}</ClerkProvider>; }
然后在layout.tsx中导入使用:
import ClerkClientProvider from './components/ClerkClientProvider'; import Navigation from './components/Navigation'; import Footer from './components/Footer'; export default function RootLayout({ children }: { children: React.ReactNode }) { return ( <html lang="en"> <body> <ClerkClientProvider> <Navigation /> <main>{children}</main> <Footer /> </ClerkClientProvider> </body> </html> ); }
3. 确保依赖无冲突
执行以下命令彻底清理并重新安装依赖,排除版本不一致问题:
# 删除依赖目录和锁文件 rm -rf node_modules package-lock.json # 重新安装依赖 npm install # 清理Next.js缓存并重启服务 npm run build && npm run dev
4. 检查ThemeProvider的位置
若你的ThemeProvider也是客户端组件,同样需要标记'use client',并确保它处于客户端组件层级中,不要在服务器组件中直接引用。
原理说明
Next.js App Router中,服务器组件禁止使用任何客户端专属API(如createContext、useState、useEffect等)。添加'use client'指令后,组件会切换到客户端环境执行,此时createContext能正常工作,Radix UI的上下文逻辑也能正确运行。
内容的提问来源于stack exchange,提问作者Abdlrhman Manoufali

