React 组件跨层级通信 Context

React 中最常用的组件的间的通信:数据是通过props属性自上而下(由父传子)一级一级进行传递的,这种传递最常用但是最麻烦,有些情况也实现不了比如:你和爷爷有小秘密不想让父传递,想自己亲口告诉你。Context 提供了一个无需为每层组件手动添加 props,就能在组件树间进行数据传递的方法(无需显示的通过组建树逐层传递)。

如何使用Context

1.创建Context对象

  const Context = React.createContext(defaultValue);

只有当组件所处的树中没有匹配到 Provider 时,其 defaultValue 参数才会生效。此默认值有助于在不使用 Provider 包装组件的情况下对组件进行测试。注意:将 undefined 传递给 Provider 的 value 时,消费组件的 defaultValue 不会生效。比如:defaultValue:'zh'

2.创建Provider,传递value

  <Context.Provider value={/* 某个值 */}>

当 Provider 的 value 值发生变化时,它内部的所有消费组件都会重新渲染。
3.子组件消费value(有三种途径:contextType,useContext,Consumer)
这三种的区别:
contextType:只能用类组件,只能订阅单一的context;useContext:函数组件(自定hook);Consumer:不限制函数组件还是类组件使用

注意事项
因为 context 会根据引用标识来决定何时进行渲染(本质上是 value 属性值的浅比较),所以这里可能存在一些陷阱,当 provider 的父组件进行重渲染时,可能会在 consumers 组件中触发意外的渲染。举个例子,当每一次 Provider 重渲染时,以下的代码会重渲染所有下面的 consumers 组件,因为 value 属性总是被赋值为新的对象:

class App extends React.Component {
  render() {
    return (
      <Context.Provider value={{something: 'something'}}>
        <Toolbar />
      </Context.Provider>
    );
  }
}

为了防止这种情况,将 value 状态提升到父节点的 state 里:

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      value: {something: 'something'},
    };
  }

  render() {
    return (
      <Context.Provider value={this.state.value}>
        <Toolbar />
      </Context.Provider>
    );
  }
}

总结:如果value是个对象记得要提出来,如果是 string,number,可以不用提,两个对象相比一直是false,那么组件每次都会刷新。

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

推荐阅读更多精彩内容