React 开发中,一般将状态放在外层组件,然后将状态通过属性一层层的传到相应的里层组件中,再渲染显示出来。例如下面这段代码,外层组件 App 有个状态 color,其以属性的形式经过 MessageList,Message 传给 Button。
1 | var Button = React.createClass({ |
但是,有时候我们不想一层层的传递属性,Context 就是帮助我们实现这个的 React 特性。
基本使用
要将外层组件的状态直接传递给里层组件,要求:
- 外层组件定义属性 childContextTypes,作为需要传递的属性类型声明
- 外层组件实例定义 getChildContext 方法,用于获取需要传递的属性值
- 里层组件定义属性 contextTypes,可以只声明需要用到属性的类型声明(没有声明的不会传递)
- 里层组件通过 this.context 获取 getChildContext 返回的值,如果没有 contextTypes,则为 undefined
1 | var Button = React.createClass({ |
在无状态组件中使用 Context
如果无状态组件有定义属性 contextTypes,那么该组件也可以引用 context。下面代码重构前面的 Button 组件:1
2
3
4
5
6
7
8function Button(props, context) {
return (
<button style={{background: context.color}}>
{props.children}
</button>
);
}
Button.contextTypes = {color: React.PropTypes.string};
Context 更新与生命周期
- 外层组件实例会在 render 后调用 getChildContext,获取到的值会传递给声明了 contextTypes 的里层组件
- 声明了 contextTypes 的里层组件会在生命周期函数获取额外的的参数 context
1 | var Button = React.createClass({ |
一般 Context 值取自外层组件状态,以便 getChildContext 获取最新的状态传递给自组件。
Context 并不是万能的,如果中间组件的 shouldComponentUpdate 返回 false,那么里层组件将无法更新。
实际运用
- 主题切换
- 响应式设计
- 登陆会话
- 语言设置