最近项目在使用React,所以准备写一些关于react的博文,方便学习和巩固。
本文将会详细讲述 v16.3 的生命周期函数,react在v16.3版本后对生命周期函数进行了较大的更新,但大部分团队不见得会跟进升到v16.3版本,所以v16.3前的生命周期还是很有必要掌握的,并且v16.3版本也是基于之前的进行修改。
React v16.3 的生命周期
在 v16.3 版本中废除的生命周期有:
- componentWillMount
- componentwillReceiveProps
- componentWillUpdate
与之增加的生命周期有:
- getDerivedStateFromProps(nextProps, prevState)
- getSnapshotBeforeUpdate
变更原因
如果开发者在以上这些render前执行的生命周期方法里面做AJAX请求的话,那AJAX将被无谓地多次调用。这明显不是我们期望的结果。而且在 componentWillMount 里发起AJAX,不管多快得到结果也赶不上首次render。
直接将这些方法禁止不能用,比劝导开发者不要这样用的效果更好,所以除了shouldComponentUpdate,其他在render函数之前的所有函数(componentWillMount,componentWillReceiveProps,componentWillUpdate)都被getDerivedStateFromProps替代。
也就是用一个静态函数 getDerivedStateFromProps 来取代被废除的几个生命周期函数,为的就是强制开发者在render之前只做无副作用的操作,而且能做的操作局限在根据props和state决定新的state。
- getDerivedStateFromProps(nextProps, prevState)
此方法作用是根据传入的 props 来更新 state。在 v16.4版本中,无论是Mounting还是Updating,也无论是因为什么引起的Updating,全部都会调用此方法。
该方法是一个 static 方法,意味着这个方法是属于 React.Component 类的方法,所以在方法内是无法使用 this 的,这就意味着无法使用 this.setState 来更新 state,所以这个方法直接通过返回对象的形式来更新 state,如果某些 props 的情况不需要更新 state,那么就返回 null 就好。
- getSnapshotBeforeUpdate(prevProps, prevState)
getSnapshotBeforeUpdate() 被调用于render之后及更新组件完成更新之前,它会获取组件的快照并作为返回值,传递给后面的 componentDidUpdate 作为它的第三个参数 ,和 componentDidUpdate 一起使用,就能覆盖掉 componentWillUpdate 的所有使用场景了。
官网给的例子:
class ScrollingList extends React.Component {
constructor(props) {
super(props);
this.listRef = React.createRef();
}
getSnapshotBeforeUpdate(prevProps, prevState) {
//我们是否要添加新的 items 到列表?
// 捕捉滚动位置,以便我们可以稍后调整滚动.
if (prevProps.list.length < this.props.list.length) {
const list = this.listRef.current;
return list.scrollHeight - list.scrollTop;
}
return null;
}
componentDidUpdate(prevProps, prevState, snapshot) {
//如果我们有snapshot值, 我们已经添加了 新的items.
// 调整滚动以至于这些新的items 不会将旧items推出视图。
// (这边的snapshot是 getSnapshotBeforeUpdate方法的返回值)
if (snapshot !== null) {
const list = this.listRef.current;
list.scrollTop = list.scrollHeight - snapshot;
}
}
render() {
return (
<div ref={this.listRef}>{/* ...contents... */}</div>
);
}
}
参考资料: