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

React Context提供的函数在子组件调用未触发预期逻辑如何解决?

问题根源

你调用useAuth()的时机和位置错误:

  • Test组件执行时,首先就会调用useAuth(),此时组件还没有渲染返回的AuthProvider,且Test组件本身处于AuthProvider的层级之外,向上找不到对应的AuthContext.Provider,所以只会取到createContext时传入的默认值,也就是打印hey的login方法、始终为null的user。
  • 只有被AuthProvider包裹的子组件内部调用useAuth,才能拿到Provider传入的自定义login、logout和user状态。
解决方案

有两种常用修正方式:

方式1:抽离内层业务组件,在Provider内部调用useAuth

修改pages/test.tsx代码如下:

// pages/test.tsx
import {AuthProvider, useAuth} from "../contexts/auth";

// 业务逻辑放到被Provider包裹的子组件内
function TestContent() {
  const {user, login, logout} = useAuth();
  console.log("user:", user); // 登录后会正确返回赋值后的user对象

  return (
    <div>
      <button onClick={login}>
        Log in
      </button>
      <button onClick={logout}>
        Log out
      </button>
    </div>
  )
}

export default function Test() {
  // Test组件只负责挂载Provider,不调用Context
  return (
    <AuthProvider>
      <TestContent />
    </AuthProvider>
  );
}

方式2:把AuthProvider提到页面上层(Next.js场景推荐)

如果你需要全站共享登录状态,可以直接把AuthProvider放到pages/_app.tsx中包裹所有页面组件,这样所有页面内部都可以直接调用useAuth,不需要每个页面单独加Provider:

// pages/_app.tsx
import type { AppProps } from 'next/app'
import { AuthProvider } from '../contexts/auth'

export default function MyApp({ Component, pageProps }: AppProps) {
  return (
    <AuthProvider>
      <Component {...pageProps} />
    </AuthProvider>
  )
}

修改后你原来的test.tsx可以简化为:

// pages/test.tsx
import { useAuth } from "../contexts/auth";

export default function Test() {
  const {user, login, logout} = useAuth();
  console.log("user:", user);

  return (
    <div>
      <button onClick={login}>
        Log in
      </button>
      <button onClick={logout}>
        Log out
      </button>
    </div>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 02:51:04