React:詳解生命週期函數-v16.3生命週期函數

最近項目在使用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>
    );
  }
}

參考資料:

詳解React生命週期(包括react16版)

React v16.3之後的組件生命週期函數

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章