Context 概念
个别用在跨组件通信中。
如下面的组件树中,A 组件与 B 组件之间隔着十分多的组件,如果 A 组件心愿传递给 B 组件一个属性,那么不得不应用 props 将属性从 A 组件历经一系列两头组件传递给 B 组件。
这样代码不仅十分的麻烦,更重要的是两头的组件可能压根就用不上这个属性,却要承当一个传递的职责,这是咱们不心愿看见的。
Context 呈现的目标就是为了解决这种场景,使得咱们能够间接将属性从 A 组件传递给 B 组件。
旧 Context(不举荐应用)
过期的 API 官网文档传送门
根本用法
假设,ABC 三个组件,AC 为祖孙关系,AB 父子关系,当初应用 context
由 A 向 C 传递属性text
。
class A extends React.Component {getChildContext() {return { text: 'Hello 孙子'}
}
render() {
return (<div> 组件 A 蕴含 <B/></div>)
}
}
A.childContextTypes = {text: PropTypes.string};
class B extends React.Component {render() {
return (<div> 组件 B 蕴含 <C/></div>)
}
}
class C extends React.Component {render() {const { text} = this.context;
return (<div> 我是 C 我接管到 A 传递的内容是{text}</div>
)
}
}
C.contextTypes = {text: PropTypes.string}
注意上述代码中用以提供 context
的API
,只有给下层组件增加 getChildContext
和childContextTypes
,React
将主动向下传递信息,子树上的所有组件能够通过定义 contextTypes
来拜访 context
。
带来的问题
如果咱们想要更新 context
,那么只能通过更新state
或者 props
并将其值赋值给context
。
class A extends React.Component {constructor(props) {super(props);
this.state = {text: 'Hello 孙子'};
}
getChildContext() {return { text: this.state}
}
updateState = () => {this.state = { text: '我是你爷爷'};
}
render() {
return (<div onClick={this.updateState} > 组件 A 蕴含 <B /></div>
)
}
}
A.childContextTypes = {text: PropTypes.string};
然而,如果 A 组件提供的一个 context
产生了变动,而两头父组件 (B) 的 shouldComponentUpdate
返回 false
,那么实际上 B 和 C 都不会进行更新。应用了 context
的组件则齐全失控,所以基本上没有方法可能牢靠的更新context
。
新 Context
官网文档传送门
还是上述例子,AC 祖孙组件通信。应用 createContext
能够构建一个 Provider
用以给孙子组件传递props
。
const defaultVal = {text: 'Hello,孙子'};
const AContext = React.createContext(defaultVal);
class App extends React.Component {constructor(props) {
...,
this.state = {text: '这里是新的内容'}
}
render() {
return (<AContext.Provider value={this.state}>
<B />
</AContext.Provider>
)
}
}
// 接管形式 1 - 定义 contextType
import {AContext} from './A';
class C extends React.Component {
static contextType = AContext;
render() {const { text} = this.context;
return (<div> 我是 C 我接管到 A 传递的内容是{text}</div>
)
}
}
// 接管形式 2 - 应用 consumer
// consumer 次要用以函数组件渲染
import {AContext} from './A';
class C extends React.Component {render() {
return (
<AContext.Consumer>
({text}) => (<p> 我是 C 我接管到 A 传递的内容是{text}</p>
)
</AContext.Consumer>
)
}
}
Redux 中的 Context
// 待续补坑