react的context用法_api接口源码

react的context用法_api接口源码React中Context的API

大家好,又见面了,我是你们的朋友全栈君。

1. Context

关于context官网文档有如下的描述:

  1. If you want your application to be stable, don’t use context. It is an experimental API and it is likely to break in future releases of React.
  2. If you aren’t familiar with state management libraries like Redux or MobX, don’t use context.
  3. If you aren’t an experienced React developer, don’t use context. There is usually a better way to implement functionality just using props and state.

综上所述就是不要使用context这个API。 虽然说不要用,但是我们也是要了解下这个API到底是干嘛的,毕竟有些优秀的库都是通过这个API实现而来,如:React-Redux。

简单了解context的作用就是在某个父组件中定义一个全局状态,这个状态可以在该父组件下的所有子组件中跨级传递共享。目前有两个版本分别是16.x之前和16.x之后的版本。

2. 老版本的Context

在老版本中有如下几个方法:

getChildContext: 在父组件中声明一个函数,返回的结果是一个对象,这个对象就是context,可以对子组件进行共享的状态。

childContextTypes: 在父组件中声明,执行context中的数据类型,如果不指定会产生错误。

contextTypes: 在子孙组件中进行声明,指定要接受context中哪些数据类型。

Tip: React.PropTypes has moved into a different package since React v15.5. Please use the prop-types library instead to define contextTypes.

如上,react15.5已经弃用React.PropTypes,需要安装prop-types库。

看个小例子:

//父组件
import React from 'react'
import DemoSun from './componets/DemoSun'
import propTyps from 'prop-types'

class Demo extends React.Component {

  getChildContext() {
    return {
      color: 'red'
    }
  }
  render() {
    return (
      <div>
        DEMO
        我是什么颜色的太阳:<DemoSun />
      </div>
    )
  }
}

Demo.childContextTypes = {
  color: propTyps.string
}

export default Demo 


//子组件
import React from 'react'
import propTyps from 'prop-types'

class DemoSun extends React.Component {

  render() {
    return (
      <div>
        DemoSun
        {this.context.color}
      </div>
    )
  }
}

DemoSun.contextTypes = {
  color: propTyps.string
}

export default DemoSun
复制代码

结果如下,子组件可以获取context中的color的值。

如果
contextTypes定义在某个组件中,则这个组件的生命周期函数中会增加一个参数:

constructor(props, context)
componentWillReceiveProps(nextProps, nextContext)
shouldComponentUpdate(nextProps, nextState, nextContext)
componentWillUpdate(nextProps, nextState, nextContext)
componentDidUpdate(prevProps, prevState, prevContext)
复制代码

如果在无状态组件中使用context则如下:

const PropTypes = require('prop-types');

const Button = ({children}, context) =>
  <button style={
   
   {background: context.color}}>
    {children}
  </button>;

Button.contextTypes = {color: PropTypes.string};
复制代码

关于老版的context就介绍到此,来关注下新版本的context。

3. 新版本的Context

新版本中使用ProviderConsumer模式,在顶层Provider中传入value,在子孙中的Consumer中获取该值,并且能够传递函数,用来修改context。

  • React.createContext(args):
const Mycontext = React.createContext(defaultValue)
复制代码

新版的是通过该方法初始化一个context对象。当React渲染了一个订阅了这个Context对象的组件,这个组件会从组件树中离自身最近的那个匹配Provider中读取到当前的context值。只有当组件所处的树中没有匹配到Provider时,其defaultValue参数才会生效。

  • Context.Provider
<Mycontext.Provider value={/*某个值*/}></Mycontext.Provider>
复制代码

每个Context对象都会返回一个Provider组件。它允许消费组件订阅context变化。其有一个value属性,传递给消费组件。一个Provider可以和多个消费组件有对应关系,多个Provider也可以嵌套使用,里层的会覆盖外层数据。

当Provider的value值发生变化时,它内部的所有消费者组件都会重新渲染。Provider及其内部consumer组件都不受shouldComponentUpdate函数的影响,无论shouldComponentUpdate返回true或者false,因此当consumer组件在其祖先组件退出更新的情况下也可以更新。

  • Class.contexType

挂载在class上的contextType静态属性会被赋值为一个由React.createContext()的Context对象。这能让你使用this.context来消费最近Context上的那个值。你可以在任何生命周期中访问它,包括在render中。

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;
复制代码
  • Context.Consumer
<MyContext.Consumer>
    {value=>/*基于context值进行渲染*/}
</MyContext.Consumer>
复制代码

这里,React组件也可以订阅到context变更。这能让你在函数式组件中完成订阅context。Consumer的children必须是一个函数。

这需要函数作为子元素这种做法。这个函数接受当前的context值,返回一个react节点。传递给函数的value值等同于往上组件树离这个context最近的Provider提供的value值。如果没有对应的Provider,value参数等于传递给createContext()的defaultValue。

4. 注意事项

context会使用参考标识来决定何时进行渲染。这样就会当provider的父组件进行重新渲染时,可能会在consumer组件中触发意外的渲染。如下:

class App extends React.Componenet{
    render() {
        return (
            <Provider value={
   
   {text: 'text'}}>
                <Demo />
            </Provider>
        )
    }
}
复制代码

如上,每次value都会创建一个新的对象。为了避免这种情况,我们可以将其提出到state中进行管理。

class App extends React.Componenet{
    constructor(props) {
        super(props)
        this.state = {
            text: 'text'
        }
    }
    render() {
        return (
            <Provider value={
   
   {text: this.state.text}}>
                <Demo />
            </Provider>
        )
    }
}
复制代码

转载于:https://juejin.im/post/5c9b102d51882547e46dd417

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/106909.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 音频放大电路设计

    音频放大电路设计目录第一章:设计要求第二章:整体思路第三章:具体电路设计1、MIC放大电路2、功率放大电路3、正弦波发生电路4、方波发生电路5、加法电路6、Line-in电路7、音频调节电路第四章:总结第五章:附录第一章设计要求1、基本要求• 功能要求:话筒扩音、音量控制、混音功能•额定功率:1W(失真度THD≤5%)•负载阻抗:8Ω•频率响应:fL≤50Hz,fH≥20kHz•输入阻抗:20kΩ•话音输入灵敏度:5mV2、提高要求音调控制特性:1kHz处增益为0d

  • 设置java环境变量path_配置java环境变量path怎么设置[通俗易懂]

    设置java环境变量path_配置java环境变量path怎么设置[通俗易懂]只需要在path中增加%JAVA_HOME%\bin;即可。完整的JDK安装及环境变量配置如下:安装JDK选择安装目录安装过程中会出现两次安装提示。第一次是安装jdk,第二次是安装jre。建议两个都安装在同一个java文件夹中的不同文件夹中。(不能都安装在java文件夹的根目录下,jdk和jre安装在同一文件夹会出错)安装jdkjre建议安装在默认位置。安装完JDK后配置环境变…

  • 什么是DrawCall?「建议收藏」

    前言游戏开发圈里的人一定听过优化游戏要降低DrawCall,这样到底什么是DrawCall呢?Unity中应该如何降低DrawCall,这里就来讲解一下关于DrawCall知识点。1.是谁拖了后腿?通俗的来说就是Cpu:(#`O′)喂你好,是Gpu吗?快点醒醒我这里又有画画的任务了(Cpu调用Gpu的次数),打一个比方比如上传很多文件到百度云或其他地方时,都会把它压缩到一个文件夹里…

  • bzero和memset哪个更耗时_malloc_trim

    bzero和memset哪个更耗时_malloc_trim 关于字符数组的初始化,在项目的压力测试中,发现性能明显下降,变怀疑在程序中的若干临时字符数组的初始化(使用bzero)身上。于是修改为首个字符置零的方式而非全部置零的方式初始化,响应得到明显的提升。原来在mp3检索的每一条结果都要进行bzero对临时数组初始化,每一个请求需要30次的bzero对临时数组的置零。于是想到了,在非必要的情况下,只对临时数组的第一个(或前几个)字符置零的初始化

    2022年10月10日
  • PC傻瓜式安装黑苹果并打造成全能逆向工作站–更新至2021.12.20

    PC傻瓜式安装黑苹果并打造成全能逆向工作站–更新至2021.12.20安装黑苹果有多简单原版Windows镜像安装大家都会,当然Ghost安装除外喔,太“乡村范儿”了。Windows操作系统的安装,无非下列四个步骤。准备镜像→写镜像到U盘→从U盘安装系统→系统自定义配置现在我们安装黑苹果也是同样的流程。先说一下本机的配置:2014年1999元买的宁美国度的组装台式机*CPU:i34160*GPU:HD4400CPU自带*RAM:4…

  • 老电脑换Linux系统是否会更快,旧电脑不要装Windows!Bodhi Linux系统,小巧强悍,运行更流畅…

    老电脑换Linux系统是否会更快,旧电脑不要装Windows!Bodhi Linux系统,小巧强悍,运行更流畅…你的旧电脑安装win10还好吗?现在科技发展越来越快,尤其是电脑硬件的更新换代,然而大多数的人都不会因为新产品出来,就将自己才用了两三年的电脑换掉。但是,电脑用久了,终究会变慢,尤其是在Windows系统功能越来愈多,越来越大的情况下,我们还是需要换电脑!不过,你的旧电脑怎么办?卖掉?它的价格分分钟还不如废铁。扔掉?又不太舍得。真是如鸡肋一般,食之无味,弃之可惜!很多人都不知道的是,其实即使是5年…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号