React Context
Context 提供了一个无需为每层组件手动添加 props, 就能在组件树间传递数据的方法
1. 何时使用 Context
通常,在一颗组件树中,如果最上层的状态,要传递到子孙组件中,那么需要中间的父级节点都将 props 进行传递:
export default function App () {
const [theme, setTheme] = useState('dark')
const clickHandle = () => {
if (theme === 'dark') {
setTheme('light')
} else {
setTheme('dark')
}
}
return <div>
<div onClick={clickHandle}>change theme</div>
<Parent theme={theme} />
</div>
}
function Parent ({ theme }) {
return <Child theme={theme} />
}
function Child ({ theme }) {
return <div>{theme}</div>
}上面这个例子,Parent 本身并不需要 theme 这个 props,只是为了传递给子组件,所以进行一个透传。
而使用 context, 就能避免透传的问题,中间元素不需要传递 props 。
2. 注意事项
一个订阅了 Context 对象的组件(即
static contextType 等于某个 Context 对象),那么这个组件就会 从父级组件中,匹配离自己最近 的 Context.Provider 提供的值当没有从父级组件中,匹配到 Context.Provider 时,将会使用
React.createContext(默认值)的默认值,Context.Provider 提供undefined时,React.createContext(默认值)的默认值 不会生效。Provider 接受 value 属性,传递给消费组件,**一个 Provider 可以有多个消费组件,多个 Provider 也可以嵌套使用,消费组件会使用最近的 Provider
数据**
当 Provider 的 value 发生变化时,内部所有消费组件都会重新渲染,重新渲染不受
shouldComponentUpdate影响检测 Provider 的 value 发生变化是根据
Object.is函数
3. Context.Consumer
在刚刚的例子中,Child 组件获取读取 context 的值,是通过指定 static contextType 来实现的
而实际上,我们还可以通过 Context.Consumer 的方式,这是一种 render props 的实现:
4. 示例
4.1 动态 Context
其实我们刚刚的例子都是 动态 Context 的例子:
即 Provider 提供的值,是一个变量,它取决于 父组件的state, 而父组件的 state 是可以随时变的。
与之对应的是 静态 Context
4.2 在嵌套组件中更新 Context
之前的例子,改变 Provider.value 的值 都是发生在顶层组件的,但是我们会有在嵌套组件中,改变 Provider.value 的需求,于是就有这个示例。
4.3 嵌套的 Context
刚刚提到多个 Provier 可以嵌套使用,以上就是嵌套使用的例子。
5. 过时的 API
在 过时的 API 中,以上 四个必须 是必须要有的。
参考文档
React 官方文档 Context
Last updated
Was this helpful?