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
// 待续补坑
发表回复