React中的context
什么是context
context就是一组属性的集合,并被_隐式_地传递给后代组件。
大家可能会有疑惑,我们不是已经有了props了吗,为什么还需要用context来传递属性呢。可以考虑这么一个情景,有一个层级很深的组件,最里层组件的行为将影响最外层的表现,一般来说我们就会在最外层组件上绑定回调,再一级一级地传入至最内层组件上,通过触发回调来进行上述行为(这里不考虑用flux)。再考虑另外一个情景,在服务端有一个组件需要根据session来渲染,当内部组件需要获取session信息时,就需要从最上层节点一层一层地往下传。但这样的实现不得不说实在有些丑陋,有没有更好的实现方式呢?有,就是使用context。
实例
import ReactDOM from 'react-dom';
import React from 'react'
// Children component
class Children extends React.Component {
constructor(props, context) {
super(props, context);
this.state = {
name: this.context.name
};
}
render() {
return(
<ul>
<li>
{`child context is: ${this.context.age}`} // child context is: 18
</li>
<li>
{`state from context: ${this.state.name}`} // state from context: mars
</li>
<li>
{`print age: ${this.context.print(this.context.age)}`} // print age: 18
</li>
</ul>
);
}
}
Children.contextTypes = {
name: React.PropTypes.string,
age: React.PropTypes.number,
print: React.PropTypes.func
};
// Parent component
class Parent extends React.Component {
getChildContext() {
return {
name: 'mars',
age: 18
};
}
render() {
return (
<div>
{`from App component: ${this.context.name}`} // from App component: bruno
<div>
{this.props.children}
</div>
</div>
);
}
}
Parent.contextTypes = {
name: React.PropTypes.string
};
Parent.childContextTypes = {
age: React.PropTypes.number,
name: React.PropTypes.string
};
// App component
class App extends React.Component {
getChildContext() {
return {
name: 'mars',
print: (m) => m
};
}
render() {
return (
<Parent>
<Children />
</Parent>
);
}
}
App.childContextTypes = {
name: React.PropTypes.string,
print: React.PropTypes.func
};
ReactDOM.render(<App />, document.getElementById('app'));
在上面的例子中,我们可以看到在App组价中声明的print
方法并没有通过Parent
传递,而是通过context
直接传递给了Children
,这大大方便了我们传值的操作,不再需要一遍一遍地写print={this.props.print}
。但同时,我们也需要注意,不要将所有东西都绑定在context
上,而是只在必要时使用context
,毕竟全局变量很危险。
使用方法
使用getChildContext
方法将属性传递给子组件,并使用childContextTypes
声明传递数据类型,子组件中需要显式地使用contextTypes
声明需要用到的属性的数据类型。
需要传递进context参数才可以在constructor方法中使用context,要不然React将会报错。
在组件中,通过this.context访问context中的属性或方法。
相关api
contextTypes
当需要在当前组件使用从上级组件传入的context的属性时,需要为用到的属性声明数据类型
childContextTypes
声明传递给子组件的属性的数据类型。
getChildContext
设置传递给子组件的属性,可以覆盖,也可以新增。
不忘初心,方得始终。