跨组件传递的内容组件,该组件导出两个对象Provider 提供数据, Consumer, 消费数据

Context被翻译为上下文,在React的官方文档中归类于高级部分,属于React的高级API,但官方并不建议在稳定版的App中使用Context。

优秀的React组件都通过Context来完成自己的功能,比如react-redux的<Provider />,就是通过Context提供一个全局态的store,拖拽组件react-dnd,通过Context在组件中分发DOM的Drag和Drop事件,
路由组件react-router通过Context管理路由状态等等
定义:

当你不想在组件树中通过逐层传递 props 或者 state 方法来传递数据时,可以使用Context来实现跨层级的组件数据传递

使用:

如果要Context发挥作用,需要用到两种组件,一个是Context生产者(Provider),通常是一个父节点,另外是一个Context的消费者(Consumer),通常是一个或者多个子节点。所以Context的使用基于生产者消费者模式。

const ThemeContext = React.createContext('light'); // 创建  

class App extends React.Component {
render() {
// 使用一个 Provider 来将当前的 theme 传递给以下的组件树。
// 无论多深,任何组件都能读取这个值。
return (
<ThemeContext.Provider value="dark">
<Toolbar />
</ThemeContext.Provider>
);
}
} // 中间的组件再也不必指明往下传递 theme 了。
function Toolbar(props) {
return (
<div>
<ThemedText />
</div>
);
} class ThemedText extends React.Component {
// 指定 contextType 读取当前的 theme context。
// React 会往上找到最近的 theme Provider,然后使用它的值。
static contextType = ThemeContext;
render() {
return <div>{this.context}</div>;
}
}
API:
  • React.createContext

    cont MyContext  = React.createContext(defaultValue);

    创建一个context对象。组件会向组件所处的树中距离最近的那个Provider进行匹配context。

    当组件所处的树没有匹配到Provider (不使用Provider组件) 时,defaultValue参数才会生效。

    • Context.Provider
<MyContext.Provider value={/* 值 */}>

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

  Provider 接收一个 value 属性,传递给消费组件。一个 Provider 可以和多个消费组件有对应关系。多个 Provider 也可以嵌套使用,里层的会覆盖外层的数据。

  当 Provider 的 value 值发生变化时,它内部的所有消费组件都会重新渲染。Provider 及其内部 consumer 组件都不受制于 shouldComponentUpdate 函数,因此当 consumer 组件在其祖先组件退出更新的情况下也能更新。

  • Class.contextType
class MyClass extends React.Component {
render() {
let value = this.context;
/* 基于 MyContext 组件的值进行渲染 */
}
}
MyClass.contextType = MyContext; // 或者像上面使用 static 定义静态变量
class MyClass extends React.Component {
static contextType = MyContext;
render() {
let value = this.context;
}
}
挂载在 class 上的 contextType 属性会被重赋值为一个由 React.createContext() 创建的 Context 对象。这能让你使用 this.context 来消费最近 Context 上的那个值。
注意:
你只通过该 API 订阅单一 context。
你可以使用 public class fields 的 static 这个类属性来初始化你的 contextType。
  • Context.Consumer

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

这种写法也可以订阅到 context,这需要函数作为子元素,这个函数接收当前的context值。

  • 对于 Provider 和 Consumer 可以这样使用:

    let { Provider, Consumer } = React.createContext();
    <Provider value={this.state.value}>
    // ...
    </Provider> <Consumer>
    { state => {
    return <div> // ... </div>
    }}
    </Consumer>

    但对于多个Context时,这种方法就无法标识是哪一个context,就需要在使用Provider和Consumer组件前调用所属Context。

    • 注意事项:

      在使用Provider时,value值如果接收一个新建对象,每次重新渲染Provider时,value属性总会被赋值为新的对象:

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

      解决这个问题,将value 状态提升到父节点的state中:

    • class App extends React.Component {
      constructor(props) {
      super(props);
      this.state = {
      value: {something: 'something'},
      };
      } render() {
      return (
      <Provider value={this.state.value}>
      <Toolbar />
      </Provider>
      );
      }
      }

React.CreateContext的更多相关文章

  1. React 之React.createContext

    使用Context,可以跨越组件进行数据传递 import React from 'react'; import ReactDOM from 'react-dom'; const ThemeConte ...

  2. React的React.createContext()源码解析(四)

    一.产生context原因 从父组件直接传值到孙子组件,而不必一层一层的通过props进行传值,相比较以前的那种传值更加的方便.简介. 二.context的两种实现方式 1.老版本(React16.x ...

  3. React 16.3来了:带着全新的Context API

    文章概览 React在版本16.3-alpha里引入了新的Context API,社区一片期待之声.我们先通过简单的例子,看下新的Context API长啥样,然后再简单探讨下新的API的意义. 文中 ...

  4. React组件设计

    React组件设计 组件分类 展示组件和容器组件 展示组件 容器组件 关注事物的展示 关注事物如何工作 可能包含展示和容器组件,并且一般会有DOM标签和css样式 可能包含展示和容器组件,并且不会有D ...

  5. React 特性剪辑(版本 16.0 ~ 16.9)

    Before you're going to hate it, then you're going to love it. Concurrent Render(贯穿 16) 在 18年的 JSConf ...

  6. react中对于context的理解

    一.context旧版的基本使用 1.context的理解 当不想在组件树中通过逐层传递props或state的方式来传递数据时,可使用context来实现跨层级的组件数据传递. 2.context的 ...

  7. [译]迁移到新的 React Context Api

    随着 React 16.3.0 的发布,context api 也有了很大的更新.我已经从旧版的 api 更新到了新版.这里就分享一下我(作者)的心得体会. 回顾 下面是一个展示如何使用旧版 api ...

  8. 盘点 React 16.0 ~ 16.5 主要更新及其应用

    目录 0. 生命周期函数的更新 1. 全新的 Content API 2. React Strict Mode 3. Portal 4. Refs 5. Fragment 6. 其他 7. 总结 生命 ...

  9. react Context

    import React, { useState, useEffect, useContext } from "react"; import axios from "ax ...

  10. react 表格扩展与编辑

    项目里有个需求是点击表格某行的工料机,显示对应定额下的工料机的表格数据,并能对两个表格进行增删改查,效果如下: 代码如下: // 引入 Component 组件 import React, { Com ...

随机推荐

  1. Git + Jenkins 自动化 NGINX 发布简易实现

    概述 之前基于 GitLab + Jenkins 实现了简单的 NGINX 的自动化发布. 具体包含如下的组件: GitLab 包括 GItLab 的 WebHook: Jenkins 及其插件: G ...

  2. 模板层语法、模板层之标签、模板的继承与导入、模型层之ORM常见关键字

    模板层语法.模板层之标签.模板的继承与导入.模型层之ORM常见关键字 一.模板层语法 1.模板语法的传值 urls代码: path('modal/', views.modal) views代码: de ...

  3. postgresql添加mysql_fdw测试过程

    请先确认已经安装好mysql_fdw,如果没有配置好点这:https://www.cnblogs.com/ohsolong/p/13041989.html 1.切换至postgres用户,输入密码登录 ...

  4. 深度复盘-重启 etcd 引发的异常

    作者信息: 唐聪.王超凡,腾讯云原生产品中心技术专家,负责腾讯云大规模 TKE 集群和 etcd 控制面稳定性.性能和成本优化工作. 王子勇,腾讯云专家级工程师, 腾讯云计算产品技术服务专家团队负责人 ...

  5. v-html渲染页面的时候 css样式无效

    感谢: https://www.cnblogs.com/niuxiaoxian/p/9443873.html 当我们用v-html渲染页面的时候会发现样式并没有添加上,如下 复制代码 <temp ...

  6. docker03-常用命令

    1.docker基础命令 1.1docker启动 指令:service docker start 1.2查看状态 指令:service docker status 1.3重启docker 指令:ser ...

  7. 逻辑运算符、成员运算符、身份运算符、流程控制、if判断、while循环

    目录 一.逻辑运算符 二.成员运算符 三.身份运算符 四.流程控制 五.分支结构 (1).单if判断 (2).双分支结构 (3).多分支结构 (4).if的嵌套使用 六.循环结构while (1).w ...

  8. C++并发-同步并发

    1.等待事件 std::mutex m; void wait() { std::unique_lock<std::mutex> lk(m); lk.unlock(); std::this_ ...

  9. NetCore使用ZipFile 和ZipOutputStream

    一.序言 环境:NetCore 3.1 项目类型:Web 二.使用ZipFile压缩本地文件 var filePath = Directory.GetCurrentDirectory() + $@&q ...

  10. K8s 网络新手教程(Kubernetes Networking Guide for Beginners)

    K8s 网络新手教程(Kubernetes Networking Guide for Beginners) 原文链接: Kubernetes Networking Guide for Beginner ...