乐趣区

react-context-学习

在 react 数据传递中常用的是通过 props 进行数据传递,但是有的内容我们是需要在整个页面中所有的组件使用的,这个时候如果还使用 props 一层一层的去去传递的话就比繁琐,怎么解决这个问题呢 react 提供了一个 context 上下文来解决这个问题。如果使用了 react-redux 进行 react 中组件之间数据传递的情况,基本是不会用到 context 的。

React.createContext

const MyContext = React.createContext(defaultValue);

创建一个 context 对象,当 react render 一个订阅了此 context 的组件的时候,他将从 Provider 中读取 context 中的值

方法的第一个参数是 defaultValue 参数只有在组件树种没有提供 Provider 组件时使用,这可以使单独测试组件变得更方便些,注意:将 undefined 作为 Provider 值传递不会导致 consumer 组件使用 defaultValue。

Context.Provider

<MyContext.Provider value={/* some value */}>

每一个 Context 对象中都包含一个 Provider 组件,在 Provider 上有一个 value 属性,这个 value 属性将能被订阅(订阅有两种方式后面会说) 了 context 的后代组件直接获取,这样就可以避免 props 向深层级的组件传递的问题了,并且订阅了 context 的组件,当 context 的值放生变化的时候组件会自动重新 render

Class.contextType

这是一种订阅 context 内容的一种方法,在类的 static 属性 contextType 设置为之前创建好的 context 对象, 在当前组件的各生命周期中使用 this.context 来访问上下文

class MyClass extends React.Component {componentDidMount() {
    let value = this.context;
    /* perform a side-effect at mount using the value of MyContext */
  }
  componentDidUpdate() {
    let value = this.context;
    /* ... */
  }
  componentWillUnmount() {
    let value = this.context;
    /* ... */
  }
  render() {
    let value = this.context;
    /* render something based on the value of MyContext */
  }
}
MyClass.contextType = MyContext;

如果你使用了 public class fields syntax 也可以使用

class MyClass extends React.Component {
  static contextType = MyContext;
  render() {
    let value = this.context;
    /* render something based on the value */
  }
}

Context.Consumer

另一种订阅 context 的方式就是使用 Comsumer 组件 ,Comsumer 组件的子组件是一个函数,这个函数的第一个参数就是 context 的值,函数的返回值必须是一个 react 的 element

<MyContext.Consumer>
  {value => /* render something based on the context value */}
</MyContext.Consumer>

官方文档
自己写的小 demo

退出移动版