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

React Context Provider未更新上下文默认值问题求助

问题根因

useSample()的调用位置错误。
React Context的取值规则是:调用useContext的组件,必须位于对应Provider组件的后代子树中,React会从该组件出发向上遍历父组件链查找最近的匹配Provider,找不到就返回createContext时定义的默认值。
你的代码执行逻辑存在本质问题:

  1. Example组件开始渲染,第一行就执行const { greetWorld } = useSample()
  2. 此时React向上查找SampleContext.Provider,但Example的所有祖先组件里根本没有挂载这个Provider——因为SampleProvider是Example自己return的JSX里的子节点,不是Example的祖先
  3. 找不到Provider,直接返回Context默认值greetWorld: false
  4. 之后才渲染SampleProvider和它内部的内容,但此时useSample的调用已经在Provider作用域外完成了,自然拿不到Provider内部设置的true值。

你之前误以为“消费组件是Provider子元素”是判断错误:写在<SampleProvider>标签中间的三元表达式只是Example组件内部的普通JSX逻辑,执行上下文归属外层的Example组件,不属于Provider的子组件范畴;useMemo也和这个问题无关,移除与否都不会影响结果。

修复方法

把消费Context的逻辑拆分到Provider包裹的独立子组件中,保证调用useContext的组件在Provider的子树范围内。
修改后的index.tsx代码如下:

import useSample, { SampleProvider } from './useSample'

// 单独拆出的子组件,位于SampleProvider内部,可以正常消费Context
const GreetingText = () => {
  const { greetWorld } = useSample()
  return greetWorld ? 'Hello world' : '...'
}

const Example = () => {
  return (
    <SampleProvider>
      <GreetingText />
    </SampleProvider>
  )
}

export default Example

useSample.tsx的现有逻辑完全正常,不需要修改。

补充说明

很多Context新手都会踩这个坑:组件自身执行的Hook,作用域归属组件本身,和组件return出去的JSX结构没有关系——哪怕你把代码写在Provider标签的中间,只要这段代码的Hook是在外层组件调用的,就不属于Provider的作用域覆盖范围。

内容的提问来源于stack exchange,提问作者Rapha-Y

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 01:21:34