react component context
在之前看react-redux
时, 说到Provider
组件是使用context
来实现的, 现在就来看看context
到底是个什么东西.
按照官方推荐的意思是, 尽量少使用context
, 因为可能会造成应用程序不稳定, 而且作为实验性的 API, 可能会在未来版本移除.
好了, 警告看完了, 下面来继续使用它吧.
基本用法
context
是帮助你的应用更简单的传递多层数据的工具. 就如同Provider
组件, 提供了一个store``props
, 那么它的子级不管多深, 只需要connect
一下, 便可以拿到该store
, 完全没有props
传递链的那种复杂写法.
1 | class Provider extends Component { |
Provider
的实现方法就差不多是这个样子, 通过它来学习context
怎么使用. 首先, 提供数据的组件需要实现getChildContext
方法, 返回一个对象, 对象值即为能提供的所有属性值, 还需要定义childContextTypes
, 表示下级可以获取到的所有属性值. 如果没有定义childContextTypes
, 那么下级的context
将得到一个空对象.connect
返回的是一个高阶组件, 这个组件定义了contextTypes
, 然后就可以在组件相关生命周期函数里面获取到对应的值了.
1 | ConnectComponent.contextTypes = { |
生命周期函数
context
在如下五个生命周期函数里面都可以获取和使用:
constructor(props, context)
componentWillReceiveProps(nextProps, nextContext)
shouldComponentUpdate(nextProps, nextState, nextContext)
componentWillUpdate(nextProps, nextState, nextContext)
componentDidUpdate(prevProps, prevState, prevContext)
无状态组件
在无状态组件中也可以使用context
, 会和props
一样, 作为函数的第二个参数传入.
1 | function FuncComponent(props, context) { |
注意shouldComponentUpdate
和props
以及state
一样, 当上级改变context
时候, 会触发下级的相关生命周期函数, 在shouldComponentUpdate
返回true
时进行重新渲染.
而与props
和state
不同的地方在于, context
是可以跨组件传递的. 这就意味着, 可能有部分中间的组件并没有使用context
, 而它们的props
和state
并没有变化, 在shouldComponentUpdate
返回false
的时候停止了子树的更新, 而子组件是使用context
获取上层数据, 但是并没有被触发更新. 这就是为什么react-router
需要使用withRouter
来包裹connect
以后的组件, 因为在connect
中实现了shouldComponentUpdate
, 会截断子树的render
.
所以react
官方并不推荐更新context
, 它应该作为一个固定的值来被全局使用, 否则可能在某些深层组件可能会出现意外的bug
.
react component context