官方对于Context的定义
React文档官网并未对Context给出“是什么”的定义,更多是描述使用的Context的场景,以及如何使用Context。
官网对于使用Context的场景是这样描述的:
In Some Cases, you want to pass data through the component tree without having to pass the props down manuallys at every level. you can do this directly in React with the powerful "context" API.
简单说就是,当你不想在组件树中通过逐层传递props
或者state
的方式来传递数据时,可以使用Context
来实现跨层级的组件数据传递。
意思就是说,当你多个组件深层嵌套后最里层的组件想要使用最外层组件的传过来的值的时候,通过props
传值就得一层层的往下传,代码很繁琐,而使用Context
,子组件就可以很方便的使用外层的父组件的值
如何使用Context (V16.x之前)
如果要Context
发挥作用,需要用到两种组件,一个是Context
生产者(Provider),通常是一个父节点,另外是一个Context
的消费者(Consumer),通常是一个或者多个子节点。所以Context的使用基于生产者消费者模式。
对于父组件,也就是Context
生产者,需要通过一个静态属性childContextTypes
声明提供给子组件的Context对象的属性,并实现一个实例getChildContext
方法,返回一个代表Context
的纯对象 (plain object) 。
父组件
class Parent extends React.Component {
getChildContext() {
return {color: "purple"};
}
}
Parent.childContextTypes = {
color: PropTypes.string
};
子组件
class Child extends React.Component {
render() {
return (
<p>
直接用过,context访问属性
{this.context.color}
</p>
);
}
}
子组件需要通过一个静态属性contextTypes声明后,
才能访问父组件Context对象的属性,否则,即使属性名没写错,
拿到的对象也是undefined
Child.contextTypes = {
color: PropTypes.string
};
V16.x之后 (更加明确了生产者消费者模式的使用方式)
通过静态方法React.createContext()
创建一个Context
对象,这个Context
对象包含两个组件,<Provider />
和<Consumer />
爷组件
import React from "react";
import ReactDom from "react-dom";
const GrandFatherContext = React.createContext({
color:'red'
});
class App extends React.Component {
render() {
return (
<GrandFatherContext.Provider>
<Father value={{color:'red'}}></Father>
</GrandFatherContext.Provider>
);
}
}
<Provider />
的value
相当于之前的getChildContext()
父组件(嵌套子组件)
class Father extends React.Component {
render () {
return (
<Son>Hello React Context API</Son>
);
}
}
class Son extends React.Component {
render () {
return (
<GrandFatherContext.Consumer>
{context => (
<h1 style={{ color: context.color}}>
{this.props.children}
</h1>
)}
</GrandFatherContext.Consumer>
)
}
}
<Consumer />
的children
必须是一个函数,通过函数的参数获取<Provider />
提供的Context
总结
新版 Context API 组成:
- React.createContext 方法用于创建一个
Context
对象。该对象包含Provider
和Consumer
两个属性,分别为两个 React 组件。- Provider 组件。用在组件树中更外层的位置。它接受一个名为
value
的 prop,其值可以是任何 JavaScript 中的数据类型。- Consumer 组件。可以在
Provider
组件内部的任何一层使用。它接收一个名为children
值为一个函数的 prop。这个函数的参数是Provider
组件接收的那个value
prop 的值,返回值是一个 React 元素(一段 JSX 代码)。