React v16.3版本后 生命周期的钩子函数的变化
前言:自从React 官方正式发布了 v16.3 版本,在这次的更新中,新引入的两个生命周期函数 getDerivedStateFromProps
,getSnapshotBeforeUpdate
以及在未来 v17.0 版本中即将被移除的三个生命周期函数 componentWillMount `,componentWillReceiveProps ,componentWillUpdate (现在这三个钩子函数依然可以使用).
static getDerivedStateFromProps(nextProps, prevState)
组件初始(重新渲染)加载时,获取当前的props与state的值(在此钩子函数中不能使用this),再此比较返回最新值对象(这个返回简单点说就相当于setState),注意添加 条件不满足时 return null;
官方例子:
static getDerivedStateFromProps(nextProps, prevState) {
if (nextProps.translateX !== prevState.translateX) {
return {
translateX: nextProps.translateX,
};
}
return null;
}
getSnapshotBeforeUpdate(prevProps, prevState)
getSnapshotBeforeUpdate
会在最终的 render 之前被调用,也就是说在 getSnapshotBeforeUpdate
中读取到的 DOM 元素状态是可以保证与 componentDidUpdate
中一致的。虽然 getSnapshotBeforeUpdate
不是一个静态方法,但我们也应该尽量使用它去返回一个值。这个值会随后被传入到 componentDidUpdate
中,然后我们就可以在 componentDidUpdate
中去更新组件的状态,而不是在 getSnapshotBeforeUpdate
中直接更新组件状态。
官方例子:
class ScrollingList extends React.Component {
listRef = null;
getSnapshotBeforeUpdate(prevProps, prevState) {
// Are we adding new items to the list?
// Capture the scroll position so we can adjust scroll later.
if (prevProps.list.length < this.props.list.length) {
return (
this.listRef.scrollHeight - this.listRef.scrollTop
);
}
return null;
}
componentDidUpdate(prevProps, prevState, snapshot) {
// If we have a snapshot value, we've just added new items.
// Adjust scroll so these new items don't push the old ones out of view.
// (snapshot here is the value returned from getSnapshotBeforeUpdate)
if (snapshot !== null) {
this.listRef.scrollTop =
this.listRef.scrollHeight - snapshot;
}
}
render() {
return (
<div ref={this.setListRef}>
{/* ...contents... */}
</div>
);
}
setListRef = ref => {
this.listRef = ref;
};
}
componentWillMount
componentWillMount在组件初次加载时调用的钩子函数,在React开发应用中,我们一般使用此钩子函数请求Axjs,用于预先加载数据。事与愿违由于Axjs异步请求数据,当开始虚拟Dom开始渲染时,数据依然没有请求得到,依然导致回流和重绘,因此Facebook团队建议使用componentDidMount钩子函数来请求API;(个人认为可以在构造函数中请求数据,虽然也不是预先加载数据的)
componentWillReceiveProps(nextProps)
在React开发中,componentWillReceiveProps
用于监听组件再次变化时(props与state变化)调用的钩子函数,一般使用于props发生改变时获取当前的数据,重新渲染页面,componentWillReceiveProps (nextProps)
是组件重新渲染时首次调用的钩子函数;componentWillUpdate(nextProps, nextState)
是组件重新渲染时将要改变Dom时调用的钩子函数;componentDidUpdate(prevProps, prevState)
是组件重新渲染完毕改变Dom结束后调用的钩子函数;重点来了: 咱们回看一下发现当组件重新渲染时,调用的这三个钩子函数功能相同,因此Facebook统一钩子函数,避免过多的钩子函数调用影响性能,因此废除componentWillReceiveProps ,componentWillUpdate ;推荐使用componentDidUpdate(prevProps, prevState)
在组件渲染完毕之后再获取当前与上一次修改的(props与state对比)重新获取当前值来进行操作
总结:
我整体对比一下可以清楚直接的看到React改版之后生命周期钩子函数的变化与简洁
改版前:
改版后:
改变之后是不是发现变化很大,简洁的多了; 以上纯属个人见解,仅供学习参考,不足之处多多指教,程序猿努力学习中...
生命周期函数 getDerivedStateFromProps,getSnapshotBeforeUpdate 以及在未来 v17.0 版本中即将被移除的三个生命周期函数 componentWillMount,componentWillReceiveProps,componentWillUpdate 也非常值得我们花点时间去探究一下其背后的原因以及在具体项目中的升级方案。