React的Context
React的context设计的目的是为一个组件树提供共享数据,不需要通过组件树一层层通过props传递(避免了中间元素传递props),具有广播的作用。
-
使用步骤:
- 创建 Context
const context=React.createContext({contextValue:'contextValue'});-
在最外层提供 要跨层级 传递的数据 Provider 有关事项:
const ContextProver=context.Provider; <ContextProver value="text"> <Child1 /> <Child1 /> <Child1 /> <ContextProver />- Provider 有关事项:
-
Provider 接收一个 value 属性
-
所有被ContextProver 包裹的组件都能接收到 ContextProver 组件传递的value值。
-
多个 Provider 也可以嵌套使用,里层的会覆盖外层的数据
state={ value:23, childValue:456 } render() { const {value,childValue}=this.state; return ( <ThemPrivider value={value}> <ThemPrivider value={childValue}> <Child /> <HookChild /> </ThemPrivider> </ThemPrivider> ) } //输出值为 456 为里面那个provider 提供的值现在增加对外面那层 provier的值进行改变,但是被包裹的Child和HookChild组件也重新render了。但是页面还有展示最内的provier的childValue 值。
export default class ThemeChild extends Component { state={ value:23, childValue:456 } clickChange=()=>{ this.setState({ value:this.state.value+2 }) } render() { const {value,childValue} =this.state; return ( <ThemPrivider value={value}> <ThemPrivider value={childValue}> <Child /> <HookChild /> </ThemPrivider> <button onClick={this.clickChange}> 改变 </button> </ThemPrivider> ) } } -
当Provider的value值发生变化的时候,它内部所有的消费者组件都会重新被渲染。
-
- Provider 有关事项:
-
在需要使用Provider提供数据的组件中使用 contextType/Consumer /useContext
// class Component 使用 contextType export default class Child extends Component { static contextType=ThemContext; render() { console.log(this.context); return ( <div> {this.context.contextValue} </div> ) } } //useContext import React,{useContext}from 'react' import {ThemContext} from './Context/index'; function HookChild(props) { const themContext= useContext(ThemContext); return ( <div> {themContext} hook </div> ) } export default HookChild -
总结: contextType 、consumer 和 useContext的区别 * contextType 只能在class组件中使用/useContext在函数式组件或者自定义hook中使用; * contextType 只能订阅单一的context来源。 * 在class组件中,如果需要使用多个provider,那么使用Consumer即可。 * useContext 可以订阅多个context。 * consumer可以在class 组件使用和可以在函数组件中使用,还可以嵌套使用并且还可以和contextType混合使用,里面是个函数 订阅多个context。 ```js
export default class Child extends Component { static contextType=ThemContext;render() { return ( <div> --- {this.context} context--- <Them2Consumer >{(con)=><div> clss{con} <ThemConsumer>{(ctx)=><span>{ctx} --ctx</span>}</ThemConsumer> </div>}</Them2Consumer> <br/> </div> ) } } ```
context特点:
- context中的值发生改变,所有包裹里面的组件都要重新render,所以性能消耗比较大。
- 在class组件中shouldComponentUpdate声明周期失效。
参考文献
- contextAPI: zh-hans.reactjs.org/docs/contex…