在一个典型的 React 应用中,数据是通过 props 属性自上而下(由父及子)进行传递的,但此种用法对于某些类型的属性而言是极其繁琐的(例如:地区偏好,UI 主题),这些属性是应用程序中许多组件都需要的。Context 提供了一种在组件之间共享此类值的方式,而不必显式地通过组件树的逐层传递 props。
通俗的讲,contextHook是React提供的比较简易的一个函数,用来实现组件间通信。
如何使用Class里的context
使用creatContext工厂函数创建Context对象
首先引入工厂函数
import {createContext} from React
创建context实例(可以选择是否传入一个default值,若不想要default值可以传入null、undefined)
const ThemeContext = React.createContext( @defaultValue );
使用实例下的Provider方法提供params
子组件需要使用一些方法来接受context
用
static
这个类属性来初始化你的contextType
。如下所示 使用类方法 ReactClass.contextType= 'context实例'
// Context 可以让我们无须明确地传遍每一个组件,就能将值深入传递进组件树。// 为当前的 theme 创建一个 context(“light”为默认值)。
const ThemeContext = React.createContext('light');
class App extends React.Component {
render() {
// 使用一个 Provider 来将当前的 theme 传递给以下的组件树。 // 无论多深,任何组件都能读取这个值。 // 在这个例子中,我们将 “dark” 作为当前的值传递下去。
return (
/* @实例下的Proveder方法 */
<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} />; }
}
使用 Context.Consumer
订阅context渲染
如果没有上级provider则读取初始化的context的DefualtValue!!!
<MyContext.Consumer>
{value => /* 基于 context 值进行渲染*/}
</MyContext.Consumer>
使用Context.displayName
指定context对象的名称
这可以让你在使用React提供的Devtools里面查看context对象。
const MyContext = React.createContext(/* some value */);
MyContext.displayName = 'MyDisplayName';
<MyContext.Provider> // "MyDisplayName.Provider" 在 DevTools 中
<MyContext.Consumer> // "MyDisplayName.Consumer" 在 DevTools 中
Tips
1. 在组件内部接受的contextValue会寻找离它最近的provider提供的参数
2. 对于模块化的context每个组件调用不受其他组件调用影响。(只要不在同一个provider内)
3. provider里的参数最好最好最好是简单类型,value本质上浅拷贝。
对于多个context可以参考下面使用方式。
function Content() {
return (
<ThemeContext.Consumer>
{theme => (
<UserContext.Consumer>
{user => (
<ProfilePage user={user} theme={theme} />
)}
</UserContext.Consumer>
)}
</ThemeContext.Consumer> );
}
如何在函数组件里使用context
基本上一致,但需要在函数组件内声明准确的需要接受的Context实例。
const value = useContext(MyContext);
简单来说,你需要在哪一个函数式组件里接受上级的provider就在那个函数组件内部声明。
而后可以直接在JSX中使用.
同样需要遵守Hook使用规则!!!
这里再强调自己一点,模块化引入的Context只要不在同一个provider互不影响。