我觉得我在放屁 但是我还得说下,上下文只能是先代创建后代使用,非先后代关系不可使用
创建上下文
只有类组件才可以创建上下文
- 给类组件书写静态属性 childContextTypes, 使用该属性对上下文中的数据类型进行约束
- 添加实例方法 getChildContext, 该方法返回的对象作为上下文中的数据,该数据必须满足约束条件,该方法会在render之后运行
使用上下文
要求: 如果要使用上下文中的数据,组件必须又一个静态属性 contextTypes, 该属性描述了需要获取的上下文中的数据类型
注意事项: 如果需要用到上下文,并且手写constructor,super要传入props和context
- 可以在组件的构造函数中,通过第二个参数获取上下文,弊端: 上下文更新后无法重新获取
- 从组建的context属性中获取 this.context
- 在函数组件中,通过第二个参数获取上下文, 切记函数组件别忘了定义静态属性 contextTypes(funcName.contextTypes = {…})
上下文的数据变化
上下文的数据不可以直接变化(this.context.a = 1),最终都是通过状态或者属性的变化而变化
在上下文中加入一个函数,用于后代组件更改上下文的值
需要react版本< 16.0.0
18版本已经不行了
Legacy context API has been detected within a strict-mode tree.
The old API will be supported in all 16.x releases, but applications using it should migrate to the new version.
import React, { Component } from 'react'
import PropTypes from "prop-types"
const types = {
a: PropTypes.number,
onChange: PropTypes.func
}
function A(props, context) {
return (
<div>
<h1>函数组件A context-a: {context.a}</h1>
<B />
</div>
)
}
A.contextTypes = {
a: types.a
}
class B extends Component {
static contextTypes = types
render() {
return (
<div>
<h1>类组件B context-a: {this.context.a}</h1>
<button onClick={()=> {
this.context.onChange(this.context.a + 1)
}}>a+1</button>
</div>
)
}
}
export default class OldContext extends Component {
static childContextTypes = types
state = {
a: 1
}
getChildContext() {
return {
a: this.state.a,
// 用箭头函数,不然this会偏
onChange: newA=> {
this.setState({
a: newA
})
}
}
}
render() {
return (
<div>
<A />
</div>
)
}
}