Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

React.createContext简介 #28

Open
deligent-ant opened this issue Nov 16, 2018 · 0 comments
Open

React.createContext简介 #28

deligent-ant opened this issue Nov 16, 2018 · 0 comments

Comments

@deligent-ant
Copy link
Contributor

React.createContext

功能:Context 旨在共享一个组件树内可被视为 “全局” 的数据,例如当前经过身份验证的用户,主题或首选语言等。(ps:树中的许多组件以及不同的嵌套级别可以访问相同的数据。)

使用

  • 允许您使用 this.context  使用该 Context 类型 的最近的当前值。 您可以在任何生命周期方法中引用它,包括 render 函数。
//.context.js文件中
import React, { Component } from 'react'
const tryContext = React.createContext({ aaa: 28288 })
export { tryContext }
  • context 对象实例

    主要是Provider Consumer这对生产者和消费者

import { tryContext } from '../components/context'
.
.
.
 class A extends PureComponent {
  render() {
    const { bbb } = this.props
    return (
      <div>
        <tryContext.Provider value={bbb}>
          <tryContext.Consumer>
            {state1 => <div className="try">{state1}</div>}
          </tryContext.Consumer>
        </tryContext.Provider>

        <tryContext.Provider value={'BBBBBB'}>
          <B />
        </tryContext.Provider>
      </div>
    )
  }
}

class B extends PureComponent {
  static contextType = tryContext
  render() {
    return <div>{this.context}</div>
  }
}
//B.contextType = tryContext

新老对比

image

老版

  1. 父组件定义 context
//父组件A
class A extends React.Component {
  getChildContext() {
    return { color: 'red' }
  }
}

A.childContextTypes = {
  color: PropTypes.string
}
  1. 子组件使用 context
//子组件B
class B extends React.Component {
  render() {
    return <p>{this.context.color}</p>
  }
}

B.contextTypes = {
  color: PropTypes.string
}

新老对比

####老版弊端

  • 代码冗余:提供 context 的组件要定义 childContextTypes 与 getChildContext 才能把 context 传下去。同时接收 context 的也要先定义 contextTypes 才能正确拿到数据。 
  • 传递效率:虽然功能上 context 可以跨层级传递,但是本质上 context 也是同 props 一样一层一层的往下传递的,当层级过深的时候还是会出现效率问题。
  • shouldComponentUpdate:由于 context 的传递也是一层一层传递,因此它也会受到 shouldComponent 的阻断。换句话说,当传递组件的 context 变化时,如果其下面某一个中间组件的 shouldComponentUpdate 方法返回 false,那么之后的接收组件将不会受到任何 context 变化。
  • 父组件 A 通过 setState 设置新的 Context 值同时触发子组件重新 render。
    子组件 B 执行 shouldComponetUpdate,由于组件 B 自身并不依赖 Context,所以 shouldComponetUpdate 检测到 state 与 prop 均未变化因此返回 false。无需重新 render。

####新版注意点

  • Provider  和  Consumer  必须来自同一次  React.createContext  调用。
  • Provider  组件的  value prop 值发生变更时,其内部组件树中对应的  Consumer  组件会接收到新值并重新执行  children  函数。此过程不受 shouldComponentUpdete 方法的影响。因此即使祖先组件退出更新,也会更新 consumer(使用者) 。
  • Provider  组件利用  Object.is  检测  value prop 的值是否有更新。(ps: <Provider value={{something: 'something'}}>不推荐,而是推荐 value 取父组件的某个 state) 4.允许您使用 this.context  使用该 Context 类型 的最近的当前值。 您可以在任何生命周期方法中引用它,包括 render 函数。您只能使用这个 API 订阅单个上下文。 5.一个 Provider 可以连接到许多 consumers (就近原则,包括 contextType 这样的使用)

参考文献
官网
头条技术博客
简书

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant