intern-study
intern-study copied to clipboard
React.createContext简介
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
新老对比
老版
- 父组件定义 context
//父组件A
class A extends React.Component {
getChildContext() {
return { color: 'red' }
}
}
A.childContextTypes = {
color: PropTypes.string
}
- 子组件使用 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 这样的使用)