Context API和useContext

解决的问题:context提供了一种在组件之间共享props的方式,而不必显示地通过组件树的逐层传递props

const MyContext = React.createContext('light');

<MyContext.Provider value='dark'>
      <MyContext.Consumer>
          {
              context => <MyComponent {...context}>
          }
      </MyContext.Consumer>
</MyContext.Provider>

class.contextType

只能用在类组件中,且只能订阅单一的context数据来源
挂载在class上的contextType属性会被重新赋值为一个由React.createContext()创建的Context对象。这样就可以使用this.context来消费最近Context上的那个值,可以在任何生命周期或者render中访问它。

使用:

MyClass.contextType = MyContext;
let value = this.context;

// 或者

static contextType = MyContext;
<Button them={this.context}/>

API:
React.createContext
当订阅了这个context对象,组件会从组件树中距离自身最近的那个provider中读取到当前的context值

只有当组件树中没有匹配到provider时,defaultValue参数才生效。

Context.Provider
每个context对象都会返回一个provider React组件,允许消费组件订阅context变化;

provider 接受一个value属性,传递给消费者;一个provider可以对应多个消费者;
多个provider可以嵌套,里层会覆盖外层;

当provider的value值发生变化时,它内部所有的消费组件都会重新渲染;provider及内部consumer组件不受shouldComponentUpdate函数限制

通过检测新旧值变化使用了object.is

注意事项:
因为context会使用参考标识来决定何时进行渲染,这时当provider的父组件进行重新渲染时,会造成consumer组件重新渲染,因为value总会被赋予新对象:

<MyContext.Provider value={{something: 'something'}}>
        <Toolbar />
 </MyContext.Provider>

//将value提升到父组件的state里边

this.state = {
      value: {something: 'something'},
};
<Provider value={this.state.value}>
        <Toolbar />
 </Provider>

==========================================
useContext:接收一个context对象并返回该context的当前值。当前context值由上层组件中距离当前组件最近的MyContext.Provider的value prop决定,useContext(MyContext) 能够读取 context 的值以及订阅 context 的变化

当上层最近的MyContext.Provider更新时,该hook会出发重新渲染,并使用传递给MyContext.Provider的value的最新值,即使祖先使用 React.memoshouldComponentUpdate,也会在组件本身使用 useContext 时重新渲染

注意事项:
调用了 useContext 的组件总会在 context 值变化时重新渲染。如果重渲染组件的开销较大,你可以 通过使用 memoization 来优化

正确使用方法✅:useContext(MyContext)

需要在上层组件树中使用 <MyContext.Provider> 来为下层组件提供 context

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容