先来看看最新版本react的生命周期图:react
React生命周期的命名一直都是很是语义化的,这个生命周期的意思就是从props中获取state,能够说是太简单易懂了。bash
能够说,这个生命周期的功能实际上就是将传入的props映射到state上面。函数
因为16.4的修改,这个函数会在每次re-rendering以前被调用,这意味着什么呢?ui
意味着即便你的props没有任何变化,而是父state发生了变化,致使子组件发生了re-render,这个生命周期函数依然会被调用。看似一个很是小的修改,却可能会致使不少隐含的问题。this
这个生命周期函数是为了替代componentWillReceiveProps存在的,因此在你须要使用componentWillReceiveProps的时候,就能够考虑使用getDerivedStateFromProps来进行替代了。spa
二者的参数是不相同的,而getDerivedStateFromProps是一个静态函数,也就是这个函数不能经过this访问到class的属性,也并不推荐直接访问属性。而是应该经过参数提供的nextProps以及prevState来进行判断,根据新传入的props来映射到state。code
须要注意的是,若是props传入的内容不须要影响到你的state,那么就须要返回一个null,这个返回值是必须的,因此尽可能将其写到函数的末尾。component
static getDerivedStateFromProps(nextProps, prevState) {
const {type} = nextProps;
// 当传入的type发生变化的时候,更新state
if (type !== prevState.type) {
return {
type,
};
}
// 不然,对于state不进行任何操做
return null;
}
复制代码
getDerivedStateFromProps exists for only one purpose. It enables a component to update its internal state as the result of changes in props.cdn
从上边这句话中,咱们能够清晰知道 getDerivedStateFromProps 的做用就是为了让 props 能更新到组件内部 state 中。因此它可能的使用场景有两个:blog
无条件的根据 prop 来更新内部 state,也就是只要有传入 prop 值, 就更新 state
只有 prop 值和 state 值不一样时才更新 state 值。
咱们接下来看几个例子。
假设咱们有个一个表格组件,它会根据传入的列表数据来更新视图。
class Table extends React.Component {
state = {
list: []
}
static getDerivedStateFromProps (props, state) {
return {
list: props.list
}
}
render () {
.... // 展现 list
}
}
复制代码
上面的例子就是第一种使用场景,可是无条件从 prop 中更新 state,咱们彻底不必使用这个生命周期,直接对 prop 值进行操做就行了,无需用 state 值类保存。
在看一个例子,这个例子是一个颜色选择器,这个组件能选择相应的颜色并显示,同时它能根据传入 prop 值显示颜色。
Class ColorPicker extends React.Component {
state = {
color: '#000000'
}
static getDerivedStateFromProps (props, state) {
if (props.color !== state.color) {
return {
color: props.color
}
}
return null
}
... // 选择颜色方法
render () {
.... // 显示颜色和选择颜色操做
}
}
复制代码
如今咱们能够这个颜色选择器来选择颜色,同时咱们能传入一个颜色值并显示。可是这个组件有一个 bug,若是咱们传入一个颜色值后,再使用组件内部的选择颜色方法,咱们会发现颜色不会变化,一直是传入的颜色值。
这是使用这个生命周期的一个常见 bug。为何会发生这个 bug 呢?在开头有说到,在 React 16.4^ 的版本中 setState 和 forceUpdate 也会触发这个生命周期,因此内部 state 变化后,又会走 getDerivedStateFromProps 方法,并把 state 值更新为传入的 prop。
接下里咱们来修复这个bug。
Class ColorPicker extends React.Component {
state = {
color: '#000000',
prevPropColor: ''
}
static getDerivedStateFromProps (props, state) {
if (props.color !== state.prevPropColor) {
return {
color: props.color
prevPropColor: props.color
}
}
return null
}
... // 选择颜色方法
render () {
.... // 显示颜色和选择颜色操做
}
}
复制代码
经过保存一个以前 prop 值,咱们就能够在只有 prop 变化时才去修改 state。这样就解决上述的问题。
这里小结下 getDerivedStateFromProps 方法使用的注意点:
在使用今生命周期时,要注意把传入的 prop 值和以前传入的 prop 进行比较。
由于这个生命周期是静态方法,同时要保持它是纯函数,不要产生反作用。