前言
React Context的概念, 前两天学习React Router时再次接触到
1 | export default React.createClass({ |
于是决定要搞明白这是个什么东东
解惑
一般而言, React中的父组件要传props
给子组件, 必须显示地指定props
的传递. 当组件层级过多时, 你可能觉得这样好麻烦, 于是React 提供了Context特性供你解决这个问题
只要父组件在Context定义了数据, 那么其下的所有子组件都可以使用Context里的数据
在组件周期函数(lifecycle methods)里可以通过
this.context
来获取Context, 经测试, 在constructor里是不可以的
父组件定义Context
1 | class Parent extends React.Component { |
childContextTypes
不可少, 否则getChildContext将报错childContextTypes must be defined in order to use getChildContext()
子组件使用Context
1 | class Child extends React.Component { |
contextTypes
不可少, 否则子组件this.context为空对象, 却不会报错
另外, 我发现在contextTypes
或childContextTypes
里面, 类型的指定可以直接使用js对象, 如下:
1 | Child.contextTypes = { |
建议
React的一个优点就是, 单向数据流, 数据的传递是清晰可见的; 使用了Context的, 数据的传递就变得隐晦起来了, 其实这就相当于在变相地使用全局变量
有人说, props
的逐层传递, 当组件层级深了, 数据也不清晰啊. 其实这个问题可以借助工具解决的, 使用react-devtools, 可以清楚地看到组件的state
及props
; 但是使用工具, 却是无法看到Context的数据的, 这的确是一个问题
官方建议适合使用Context的来来传递的数据应该是: 登录后的用户信息, 当前语言种类, 或主题信息
因为Context 是在React v0.14 版本以后发布的一个实验性的功能,官方有提醒其API在未来有可能会更改, 因此在实践中除了上述情况外, 最好避免使用它. 在此我也就简单地介绍一下, 更多详情请看官方文档
参考资料
附录
前言中代码里, 为什么Route里的组件可以从Context获取router
对象呢? 这是因为React Router会创建RouterContext, 作为所有Route的父组件, 而RouterContext有如下代码, 定义了Context:
1 | childContextTypes: { |