關于react的新生命周期

在react中舊的生命周期其實已經(jīng)十分完整,基本可以捕捉到組件更新的每一個state/props/ref,沒有什從邏輯上的毛病。

1. 舊的生命周期
舊的生命周期

當然我們現(xiàn)在,在整個16版本里都能無障礙的使用舊的三生命周期,但舊的生命周期(unsafe)不能和新的生命周期同時出現(xiàn)在一個組件,否則會報錯。

可以看出三個即將被刪除的生命周期,都是在實際dom掛載之前的虛擬dom構建階段。這也正是react打算在17版本推出新的Async Rendering,提出一種可被打斷的生命周期,而可以被打斷的正是即將要被去掉的三個生命周期。生命周期一旦被打斷,下次恢復的時候又會再跑一次之前的生命周期了。

2. 新的生命周期

接下來我們看下新增的生命周期:

  1. static getDerivedStateFromProps
  • 觸發(fā)時間:掛載組件時,該靜態(tài)方法會在render前執(zhí)行;更新組件時,該靜態(tài)方法會在shouldComponentUpdate前執(zhí)行。
  • 每次接收新的props之后都會返回一個對象作為新的state,返回null則說明不需要更新state.
  • getDerivedStateFromProps是一個靜態(tài)方法,是拿不到實例this的,所以開發(fā)者應該將該函數(shù)設計成純函數(shù)。
  • getDerivedStateFromProps 中還禁止了組件去訪問 this.props,強制讓開發(fā)者去比較 nextPropsprevState 中的值,以確保當開發(fā)者用到getDerivedStateFromProps 這個生命周期函數(shù)時,就是在根據(jù)當前的 props來更新組件的 state,而不是去做其他一些讓組件自身狀態(tài)變得更加不可預測的事情。

乍看下來 static getDerivedStateFromProps和即將被刪掉componentWillReceiveProps這二者好像并沒有什么本質上的區(qū)別,但這卻是這其實是最能夠體現(xiàn) React 團隊對于軟件工程深刻理解的一個改動,即 React 團隊試圖通過框架級別的 API 來約束或者說幫助開發(fā)者寫出可維護性更佳的 JavaScript 代碼。

class test extends Component {
    // before
  componentWillReceiveProps(nextProps) {
    if (nextProps.isSupportCaps !== this.props.isSupportCaps) {
      this.setState({   
        isSupportCaps: nextProps.isSupportCaps, 
      });
    }
    if (nextProps.isSupportCaps) {
      this.handleCaps();
    }
  }

  // after
  static getDerivedStateFromProps (nextProps, prevState) {
    if (nextProps.isSupportCaps !== prevState.isSupportCaps) {
      return {
        isSupportCaps: nextProps.isSupportCaps,
      };
    }
    return null;
  }
  componentDidUpdate(prevProps, prevState) {
    if (!prevState.isSupportCaps && this.props.isSupportCaps) {
      this.handleCaps();
    }
  }
}

在新版本中,官方將更新 state 與觸發(fā)回調重新分配到了 getDerivedStateFromPropscomponentDidUpdate 中,使得組件整體的更新邏輯更為清晰。

  1. getSnapshotBeforeUpdate
  • 觸發(fā)時間: update發(fā)生的時候,在render之后,在組件dom渲染之前。
  • 返回一個值,作為componentDidUpdate的第三個參數(shù)。
  • 配合componentDidUpdate, 可以覆蓋componentWillUpdate的所有用法。
    官方提供的一個例子如下:
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;
  };
}

getSnapshotBeforeUpdate 的使用場景一般是獲取組建更新之前的滾動條位置。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 作為一個合格的開發(fā)者,不要只滿足于編寫了可以運行的代碼。而要了解代碼背后的工作原理;不要只滿足于自己的程序...
    六個周閱讀 8,684評論 1 33
  • 深入JSX date:20170412筆記原文其實JSX是React.createElement(componen...
    gaoer1938閱讀 8,187評論 2 35
  • 變更的部分 react v16.3終于出來了,最大的變動莫過于生命周期去掉了以下三個 componentWillM...
    芝麻香油閱讀 573評論 0 1
  • 為了幫助大家快速上手React Native開發(fā),在這本節(jié)中將向大家介紹開發(fā)React Native所需要的一些R...
    CrazyCodeBoy閱讀 1,959評論 1 9
  • 你有沒有在大狂歡時一瞬間落寞狂涌而來,就像溺水的孩子般掙扎無助。 只是再也開心不起來。
    殳聲閱讀 359評論 0 0

友情鏈接更多精彩內容