跨组件传递的内容组件,该组件导出两个对象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. 解决安装node-sass报错的方法

    1.下载源码放到本地搞~~ 适合内网开发的苦孩子们~~~ 先进入https://github.com/sass/node-sass/releases下载自己需要的包 可以点击tags然后找到自己需要的 ...

  2. webpack配置less以及js中引入的图片问题

    1.问题重现 当我做了这个配置以后,发现less里的图片可以正常展现到页面,但是js里的图片以及其他文件都不能正常展现,都报404 原始配置如下: // 如果有額外的.babelrc配置的話就可以使用 ...

  3. Python3+Selenium3自动化测试-(六)

    这里来说一说selenium中的等待方式,其实在webdriver只有两种类型等待方式,显式等待和隐式等待,之前是在程序运行过程中使用time模块中的sleep进行代码的休眠进行强制等待,是显式等待中 ...

  4. 读Java8函数式编程笔记07_设计和架构的原则

    1. SOLID原则 1.1. 开发良好面向对象程序的准则 1.2. Liskov substitution里氏替换 1.3. Interface segregation接口隔离 1.4. Singl ...

  5. TS不能将类型“any[]”分配给类型“never[]”

    一.问题 在处理接口返回的数据,赋值给store中的数组时,报类型错误 data:{ cateList: [] } const getCateList = async () => { const ...

  6. ChatGPT保姆级注册教程

    ChatGPT保姆级注册教程 最近几天OpenAI发布的ChatGPT聊天机器人火出天际了,连着上了各个平台的热搜榜.这个聊天机器人最大的特点是模仿人类说话风格同时回答大量问题. 有人说ChatGPT ...

  7. 12月20日内容总结——ajax补充知识点、多对多外键的三种创建方式、django内置序列化组件、批量操作数据、分页器推导思路与自定义分页器的使用、form组件

    目录 一.ajax补充说明 二.多对多三种创建方式 三.django内置序列化组件(drf前身) 四.批量操作数据 五.分页器思路 六.自定义分页器的使用 七.form组件 forms组件介绍 For ...

  8. Android第六次作业

    图片一 用内部存储实现文件写入和读取功能 <?xml version="1.0" encoding="utf-8"?> <LinearLayo ...

  9. websocket-sharp 实现websocket

    第一步,使用VS创建一个应用程序 第二步,添加引用 websocket-sharp DLL文件,或者NuGet程序包中添加 第三部,创建Laputa 类 using WebSocketSharp; u ...

  10. javaweb-LoginDemo在JdbcTemp的登录实现及总结+进阶javabean改进

    刚开始发现- -我好像忘记了JdbcTemp的知识了,以为自己学漏了,重新回去看了一下,还好还记得,所以今天做一个案例: 案例分析: 登录的实现 步骤: 先导入jar包,然后写一个简单的html页面 ...