React context

关于context的官方文档
https://reactjs.org/docs/context.html
这个网址可能要番羽土廧

简单解释一下,context就相当于一个全局变量一样的,在一个组件树中,根组件传递值或者方法给子孙后代组件,需要一层一层的传,相当麻烦。
而这个context,定义了组件树的共享上下文,使得传递值,不需要经过中间组件,也有人戏称为react中的虫洞。

React context的API有两个版本,React16.x之前的是老版本的context,之后的是新版本的context。
先来学习老版本的怎么用

先来定义一个根组件A,然后getChildContext是固定的api接口,定义全局共享的上下文,这个return的对象里面塞入的是你要传递的东西(比如说这里传递的是user这个人的信息给子孙组件)

class A extends React.Component {
  getChildContext() {
    return {
      user: this.props.user,
      text: "item text"
    }
  }
  
  render() {
    
{this.props.children}
} } A.childContextTypes = { user: React.PropTypes.object.isRequired, text:React.PropTypes.string.isRequired }

要在后面指定组件A的传入验证A.childContextTypes,不指定的话,会产生错误
然后在后代组件中这样使用(这里我们定义一个组件D,是根组件A的后代元素)

class D extends React.Component {
  render() {
    
{this.context.user.name}
} } D.contextTypes = { user: React.PropTypes.object.isRequired }

这里也要定义D的contextTypes,可以只定义context中的部分,例如我这里,只定义了user,没有定义text,也是ok的,如果这里的contextTypes没有定义,那么用this.context获取到的,将是一个空对象。

从React v15.5开始 ,React.PropTypes 助手函数已被弃用,可使用 prop-types 库 来定义contextTypes

  • 老的context 有个问题就是,shouldComponentUpdate这个生命周期函数,一般用来优化性能,减少渲染次数,这个生命周期函数只检测state和prop的值,如果上下文context的值变动了,它并不能检测到,所以就不会render,那么这个组件的子组件,也不会重新render,无法获得新的context的值

  • 新版本解决了上面这个问题

那么再来看看新版本怎么使用这个api

新版本的用法有点像react-redux,外层使用Provider包裹,然后在value处注入上下文环境,然后后代组件用Customer包裹,用来接收上下文

import React, { Component } from 'react';
const Test1Context = React.createContext({
    user:{name:"asdf"},
    text:"asdfdsaf"
});
class A extends React.Component {
    state ={
      user: this.props.user,
      text: "item text"
    }
    render() {
        
            
{this.props.children}
} }
  • React.createContext()传入的东西用于设置默认值,也可以不传。
  • 这个包裹的Provider,要改成你定义的上下文名字+.Provider,这里我定义的上下文环境名字叫 Test1Context,所以我render里面包裹的是Test1Context.Provider。
  • value里可以放任意的东西,比如放一个对象,放个数组,放个字符、数字,放个function,都ok。

然后再是后代组件D

class D extends React.Component {
  render() {
    
        
{this.context.user.name} {(value)=>
value.user.name
} {({user})=>
user.name
}
} } D.contextType = Test1Context ; (或者在D里面 static contextType = Test1Context )

可以在生命周期里面使用,官方文档是这样写的

 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;

你可能感兴趣的:(React context)