惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

罗磊的独立博客
SecWiki News
SecWiki News
酷 壳 – CoolShell
酷 壳 – CoolShell
爱范儿
爱范儿
量子位
M
MIT News - Artificial intelligence
GbyAI
GbyAI
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
TaoSecurity Blog
TaoSecurity Blog
博客园 - 【当耐特】
H
Heimdal Security Blog
腾讯CDC
The Last Watchdog
The Last Watchdog
Security Archives - TechRepublic
Security Archives - TechRepublic
Hacker News: Ask HN
Hacker News: Ask HN
S
Schneier on Security
Microsoft Security Blog
Microsoft Security Blog
WordPress大学
WordPress大学
博客园 - 司徒正美
Recent Commits to openclaw:main
Recent Commits to openclaw:main
C
Cybersecurity and Infrastructure Security Agency CISA
S
SegmentFault 最新的问题
大猫的无限游戏
大猫的无限游戏
Application and Cybersecurity Blog
Application and Cybersecurity Blog
F
Full Disclosure
有赞技术团队
有赞技术团队
T
Tailwind CSS Blog
Engineering at Meta
Engineering at Meta
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
T
Threatpost
月光博客
月光博客
A
Arctic Wolf
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
雷峰网
雷峰网
T
Troy Hunt's Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
The Cloudflare Blog
D
DataBreaches.Net
O
OpenAI News
L
LINUX DO - 最新话题
宝玉的分享
宝玉的分享
小众软件
小众软件
V
Vulnerabilities – Threatpost
A
About on SuperTechFans
人人都是产品经理
人人都是产品经理
T
The Exploit Database - CXSecurity.com
Martin Fowler
Martin Fowler
美团技术团队
P
Privacy International News Feed

博客园 - 君临天下之徐少

nvm安装 Homebrew 安装 Less的优点 什么是nrm js 处理大数相减 React函数式组件值之useRef()和useImperativeHandle() 谷歌刷题插件安装 SSL certificate problem: unable to get local issuer certificate 错误解决 常用命令 Mac安装Nvm Node开发环境 解决Mac安装Homebrew失败 Canvas学习:globalCompositeOperation详解 html让容器居中,css让容器水平垂直居中的7种方式 js下载文件防止白屏 GitHub上README.md编写教程(基本语法) 微信字体大小调整导致的H5页面错乱问题处理 G6-Editor 编辑器入门使用教程 git reset 加不加 --hard的区别 taro, h5拨打电话和发送短信
React.CreateContext
君临天下之徐少 · 2022-05-31 · via 博客园 - 君临天下之徐少
跨组件传递的内容组件,该组件导出两个对象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>
          );
        }
      }