最近項目在使用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>
);
}
}
參考資料: