首页 > 专栏 > 前端 > 文章详情
React 的 context 的 API 解释 发布于:2021-03-26 17:18:37   来源:React   查看:2  讨论:0
React.CreateContext(也就是说后面的值书写就是一个习惯)
const MyContext = React.createContext(defaultValue);
创建一个 Context 对象。当 React 渲染一个订阅了这个 Context 对象的组件,这个组件会从组件树中离自身最近的那个匹配的 Provider 中读取到当前的 context 值。
只有当组件所处的树中没有匹配到 Provider 时,其 defaultValue 参数才会生效。此默认值有助于在不使用 Provider 包装组件的情况下对组件进行测试。注意:将 undefined 传递给 Provider 的 value 时,消费组件的 defaultValue 不会生效。
Context.Provider(这个值很关键,基本上等于同真正第一次用到的值)
<MyContext.Provider value={/* 某个值 */}>
每个 Context 对象都会返回一个 Provider React 组件,它允许消费组件订阅 context 的变化。
Provider 接收一个 value 属性,传递给消费组件。一个 Provider 可以和多个消费组件有对应关系。多个 Provider 也可以嵌套使用,里层的会覆盖外层的数据。
当 Provider 的 value 值发生变化时,它内部的所有消费组件都会重新渲染。
Provider 及其内部 consumer 组件都不受制于 shouldComponentUpdate 函数,因此当 consumer 组件在其祖先组件退出更新的情况下也能更新。
通过新旧值检测来确定变化,使用了与 Object.is 相同的算法。
Class.contextType(这是一个不分地点出现的属性,哪里要用this.context,就在这里的下面声明这个属性,挂到该组件下)
class MyClass extends React.Component {
  componentDidMount() {
    let value = this.context;
    /* 在组件挂载完成后,使用 MyContext 组件的值来执行一些有副作用的操作 */
  }
  componentDidUpdate() {
    let value = this.context;
    /* ... */
  }
  componentWillUnmount() {
    let value = this.context;
    /* ... */
  }
  render() {
    let value = this.context;
    /* 基于 MyContext 组件的值进行渲染 */
  }
}
MyClass.contextType = MyContext;

挂载在 class 上的 contextType 属性会被重赋值为一个由 React.createContext() 创建的 Context 对象。sLx易塔云建站-模板下载,web开发资源,技术博客
此属性能让你使用 this.context 来消费最近 Context 上的那个值。你可以在任何生命周期中访问到它,包括 render 函数中。sLx易塔云建站-模板下载,web开发资源,技术博客
Context.Consumer(一般和Provider配套使用,内容是一个child fun,用得到的context值进行渲染JSX语句)sLx易塔云建站-模板下载,web开发资源,技术博客

<MyContext.Consumer>
  {value => /* 基于 context 值进行渲染*/}
</MyContext.Consumer>

一个 React 组件可以订阅 context 的变更,此组件可以让你在函数式组件中可以订阅 context。sLx易塔云建站-模板下载,web开发资源,技术博客

这种方法需要一个函数作为子元素(function as a child)。这个函数接收当前的 context 值,并返回一个 React 节点。sLx易塔云建站-模板下载,web开发资源,技术博客
传递给函数的 value 值等价于组件树上方离这个 context 最近的 Provider 提供的 value 值。sLx易塔云建站-模板下载,web开发资源,技术博客
如果没有对应的 Provider,value 参数等同于传递给 createContext() 的 defaultValuesLx易塔云建站-模板下载,web开发资源,技术博客
真实案例:sLx易塔云建站-模板下载,web开发资源,技术博客

function ThemeToggleButton() {
    // let theme = this.context;
    return(
        // 这里不写.Consumer也能用,不过以后可能会消失
        // 写了Consumer属性,就无须再用contextType方法去定义了,已经可以获得当前的context值(this.context)
        //  Context.Consumer:这种方法需要一个函数作为子元素。这个函数接收当前的context值,并返回一个react节点。
        //  传递给函数的value值等价于组件树上离这个context最近Provider提供的value值。
        //  如果没有对应的Provider,value参数等于传递给createContext()的defaultValue。
        //  语法:<MyContext.Consumer>
        //  {value => /*基于 context 值进行渲染*/ }
        //  </MyContext.Consumer
        <ThemeContext.Consumer>
          {({theme, toggleColor}) => (
              <button onClick={toggleColor} style={{backgroundColor: theme}}>切换颜色</button>
          )}
        </ThemeContext.Consumer>
    )
}
Context.displayName(基本等于没用)sLx易塔云建站-模板下载,web开发资源,技术博客
context 对象接受一个名为 displayName 的 property,类型为字符串。sLx易塔云建站-模板下载,web开发资源,技术博客
React DevTools 使用该字符串来确定 context 要显示的内容。
const MyContext = React.createContext(/* some value */);
MyContext.displayName = 'MyDisplayName';
<MyContext.Provider> // "MyDisplayName.Provider" 在 DevTools 中
<MyContext.Consumer> // "MyDisplayName.Consumer" 在 DevTools 中

评论

  • 匿名