Context
React.js中,某个组件往自己的context
里面放了某些状态,这个组件之下的所有子组件都可以直接访问这个状态,而不需要通过中间组件的传递。一个组件的context
只有子组件能够访问,它的父组件是不能访问的。
|
|
getChildContext
方法是用来设置context
,返回的对象就是context
,所有的子组件都是可以访问到这个对象。childContextTypes
是用来验证getChildContext
返回的对象必须要写。因为context
是一个危险的特性,React.js团队想把危险的东西搞得复杂一点,提高使用门槛。
|
|
子组件想要获取context
里面的内容,就必须写contextTypes
来声明和验证你需要获取的状态的类型,它也是必写的,否则无法获取context
里面的状态。
一个组件中定义了contextTypes
,那么在以下生命周期中,将会收到额外的参数,即 context
对象
constructor(props, context)
componentWillReceiveProps(nextProps, nextContext)
shouldComponentUpdate(nextProps, nextState, nextContext)
componentWillUpdate(nextProps, nextState, nextContext)
componentDidUpdate(nextProps, nextState, nextContext)
安全更新Context
当state
或者props
更新时getChildContext
方法会被调用,为了更新context
,使用this.setState
来更新本地state
,这将会生成一个新的context
,所有子组件都会接收到更新。
但如果有一个中间的父组件的shouldComponentUpdate
返回了false
(或者PureComponent
组件),那么他的子组件context
就不会被更新。
为了解决这个问题,可以通过基于context
依赖注入进行变更。在适当的地方,建立一个依赖注入系统,然后向下传递需要管理的状态并订阅它。
调用
forceUpdate()
将会导致组件的render()
方法被调用,并忽略shouldComponentUpdate()
。这将会触发每一个子组件的生命周期方法,涵盖,每个子组件的shouldComponentUpdate()
方法。
我们创建了一个Theme
对象来保存状态,Theme
对象同时也是一个事件发射器,这可以让像Title
一样的组件来订阅未来的变化,Theme
对象通过ThemeProvider
在组件树中传递。只有刚开始的时候传递了context
,后面的更新都通过Theme
自己来传播,并没有重新创建一个context
。