React中的上下文
Context
上下文: 表示做某一些事情的环境。类似于语言环境中的上下文,上下文这个东西不是一个具体的东西,在不同的地方表示不同的含义,理解为环境比较好。
知乎上一个关于上下文的问题:编程中什么是「Context(上下文)」?
React 中的 Context: 组件可以创建一个上下文,上下文中的数据可以被所有的后代组件共享,而不需要层层传递
例如这样的一个组件结构:
1 | function App() { |
如果 <Cmp1 /> 创建了一个上下文,那么情况就是这样的:
Cmp1 组件的子组件可以直接使用上下文中的数据,而无需通过 props 层层传递。

React 中上下文的特点:
- 当某个组件创建了上下文后,上下文中的数据,会被所有后代组件共享
- 如果某个组件依赖了上下文,会导致该组件不再纯粹
旧 Context API
旧版的 API 不建议使用,React 版本 < 16
创建上下文
对于旧的 API 只有类组件才可以创建上下文
-
给类组件书写静态属性
childContextTypes,使用该属性对上下文中的数据类型进行约束 -
添加实例方法
getChildContext,该方法返回的对象即为上下文中的数据,该数据必须满足类型约束,该方法会在每次render之后运行
1 | class App extends React.Component { |

使用数据
要求:如果要使用上下文中的数据,组件必须有一个静态属性 contextTypes,该属性描述了需要获取的上下文中的数据类型
类组件
- 构造函数实际会传入第二个参数
context,执行super(props, ctx) - 通过
this.context获取上下文中的数据
1 | import PropTypes from "prop-types"; |
函数组件
通过第二个参数,获取上下文数据:
1 | function Cmp(props, ctx) { |

新 Context API
创建上下文
上下文是一个独立于组件的对象,该对象通过 React.createContext(defaultValue) 创建
1 | const ctx = React.createContext({ a: 1, b: 2 }); |

该对象有两个对象属性(都是组件):
Provider:该组件会创建一个上下文,该组件有一个value属性,通过该属性传入上下文中的值Consumer:该组件用于接收上下文中的数据,需要给该组件传入一个children,且必须是一个函数,函数的参数为上下文value
使用数据
通过 Consumer 组件使用上下文中的数据
1 | const ctx = React.createContext(); |

类组件
对于类组件,除此之外依旧可以使用 this.contex 来获取上下文中的数据,但是需要提供一个静态属性 contextType 存储上下文对象。
1 | class Cmp3 extends React.Component { |
函数组件
对于函数组件,可以使用 context hook 来使用上下文中的数据。
1 | function Child() { |
细节:
如果 Context.Provider 的 value 属性发生变化 (使用 Object.is 比较),会导致该上下文提供的所有后代元素全部重新渲染,无论该子元素是否有优化(无论 shouldComponentUpdate 函数返回什么结果)。








