PAYATHON 2026

Next.js App Router 构建时 useContext 报错如何排查?

数据小陈

结论

在 App Router 中,可以在 RootLayout 下挂载全局客户端 Provider,再让 Header、Footer 等客户端组件在 Provider 内通过 useContext 读取 Context。use client 用来标记客户端组件边界,但这些组件仍可能参与服务端预渲染,因此它不会关闭 SSR。

先核对当前的版本组合。Next.js 16 要求 Node.js 20.9 或更高版本,而问题中提供的环境是 Node.js 18+。Next.js 16 的 App Router 也使用 React 19.2 相关运行时能力。建议先按 Next.js 16 的要求对齐 Node.js 和 React 依赖,再检查组件边界和依赖安装情况。Next.js 16 升级指南

在 RootLayout 中挂载客户端 Provider

RootLayout 可以继续作为 Server Component。将 Context、Provider 和使用 Context 的组件放在客户端模块中,并确保这些消费者位于 Provider 的子树内:

// app/providers.tsx
'use client'

import { createContext, useContext } from 'react'

const AppContext = createContext<string | null>(null)

export function AppProvider({ children }: { children: React.ReactNode }) {
  return <AppContext.Provider value="ready">{children}</AppContext.Provider>
}

export function Header() {
  const value = useContext(AppContext)
  return <header>{value}</header>
}
// app/layout.tsx
import { AppProvider, Header } from './providers'
import Footer from './footer'

export default function RootLayout({
  children,
}: Readonly<{ children: React.ReactNode }>) {
  return (
    <html lang="zh-CN">
      <body>
        <AppProvider>
          <Header />
          {children}
          <Footer />
        </AppProvider>
      </body>
    </html>
  )
}

如果 Footer 也要读取这个 Context,它同样需要是客户端组件,并从同一个 Context 模块导入 Context。服务端组件不能直接调用 useContext 或其他 React Hook。

结合这条报错排查

useContext 读取到 null,不能单凭这一点认定是“服务端不能使用客户端 Context”。可以按下面的顺序检查:

  1. 对齐运行环境和依赖版本。 将 Node.js 升级到 Next.js 16 要求的版本,并使用项目模板或升级指南推荐的 next、react、react-dom 组合。确认 react 与 react-dom 版本一致。工作区或依赖树中安装了多份 React,也可能导致 Hook 运行时异常。
  2. 确认 Provider 的覆盖范围。 检查出错的 Header、Footer 是否确实渲染在对应 Provider 内,并确认它们与 Provider 导入的是同一个 Context 实例。
  3. 检查 Hook 的调用位置。 useContext 必须在函数组件或自定义 Hook 的顶层调用,不能放在普通函数、条件分支中,也不能在组件渲染之外调用。
  4. 检查浏览器专属逻辑。 如果组件渲染时直接读取 window、localStorage 等浏览器对象,可以把读取操作放进 useEffect,或改用只在客户端渲染的设计。客户端组件也会参与预渲染,因此首次渲染不一定只发生在浏览器中。
  5. 处理 key 警告。 日志中的 Each child in a list should have a unique ("key") prop 表示列表子元素缺少稳定的 key,需要给映射生成的元素补上唯一 key。这项警告需要修复,但不能据此断定它导致了 useContext 异常。

目前没有提供具体的 Provider、Header 或 Footer 实现,因此无法从日志判断 useContext 报错的确切原因。结合现有信息,建议先检查版本组合和 Provider 的覆盖范围。

备注:内容仅供参考。