context提供了一个无需为每层组件手动添加props,就能在组件树间进行数据传递的方法
如果你只是想避免层层传递一些属性,组件组合(component composition)有时候是一个比 context 更好的解决方案。
使用API:
- React.createContext(defaultValue):创建context对象
const MyContext = React.createContext('test');
-
MyContext.Provider:是一个React组件,允许消费组件订阅context的变化.
Provider 接收一个 value 属性,传递给消费组件。一个 Provider 可以和多个消费组件有对应关系。多个 Provider 也可以嵌套使用,里层的会覆盖外层的数据。
当 Provider 的 value 值发生变化时,它内部的所有消费组件都会重新渲染。Provider 及其内部 consumer 组件都不受制于 shouldComponentUpdate 函数,因此当 consumer 组件在其祖先组件退出更新的情况下也能更新
<MyContext.Provider value='test1'>
</MyContext.Provider>
-
MyContext.Consumer:在函数组件中消费/使用context
这需要函数作为子元素这种做法。这个函数接收当前的 context 值,返回一个 React 节点。传递给函数的value
值等同于往上组件树离这个 context 最近的 Provider 提供的value
值。如果没有对应的 Provider,value
参数等同于传递给createContext()
的defaultValue
。
<MyContext.Consumer>
{value => /* 基于 context 值进行渲染的React节点*/}
</MyContext.Consumer>
总体:
const MyContext = React.createContext();
const Child = ()=>(
<MyContext.Consumer>
{value=><div>value[0].name</div>}
</MyContext.Consumer>
);
const App = ()=>(
<MyContext.Provider value={[name:1]}>
<Child/>
</MyContext.Provider>
);
-
useContext:通过hook,在函数组件中消费/使用context
在上例中,使用useContext如下:
const MyContext = React.createContext();
const Child = ()=>{
const value=useContext(MyContext);
return {
value=><div>value[0].name</div>
}
};
const App = ()=>(
<MyContext.Provider value={[name:1]}>
<Child/>
</MyContext.Provider>
);
- Class.contextType:挂载在 class 上的
contextType
属性会被重赋值为一个由React.createContext()创建的 Context 对象。在类组件中使用this.context
来消费最近 Context 上的那个值。可以在任何生命周期中访问到它,包括 render 函数中。
// Context 可以让我们无须明确地传遍每一个组件,就能将值深入传递进组件树。
// 为当前的 theme 创建一个 context(“light”为默认值)。
const ThemeContext = React.createContext('light');
class App extends React.Component {
render() {
// 使用一个 Provider 来将当前的 theme 传递给以下的组件树。
// 无论多深,任何组件都能读取这个值。
// 在这个例子中,我们将 “dark” 作为当前的值传递下去。
return (
<ThemeContext.Provider value="dark">
<Toolbar />
</ThemeContext.Provider>
);
}
}
// 中间的组件再也不必指明往下传递 theme 了。
function Toolbar() {
return (
<div>
<ThemedButton />
</div>
);
}
class ThemedButton extends React.Component {
// 指定 contextType 读取当前的 theme context。
// React 会往上找到最近的 theme Provider,然后使用它的值。
// 在这个例子中,当前的 theme 值为 “dark”。
static contextType = ThemeContext;
render() {
return <Button theme={this.context} />;
}
}
- MyContext.displayName:context 对象接受一个名为 displayName 的 property,类型为字符串。React DevTools 使用该字符串来确定 context 要显示的内容