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。