【React 資料備份】React v16.3以後的生命週期

React v16.4 的生命週期圖服務器

img

React v16.4 的生命週期async

變動原因

原來(React v16.0前)的生命週期在React v16推出的Fiber以後就不合適了,由於若是要開啓async rendering,在render函數以前的全部函數,都有可能被執行屢次。函數

原來(React v16.0前)的生命週期有哪些是在render前執行的呢?this

  • componentWillMount
  • componentWillReceiveProps
  • shouldComponentUpdate
  • componentWillUpdate

若是開發者開了async rendering,並且又在以上這些render前執行的生命週期方法作AJAX請求的話,那AJAX將被無謂地屢次調用。。。明顯不是咱們指望的結果。並且在componentWillMount裏發起AJAX,無論多快獲得結果也趕不上首次render,並且componentWillMount在服務器端渲染也會被調用到(固然,也許這是預期的結果),這樣的IO操做放在componentDidMount裏更合適。code

禁止不能用比勸導開發者不要這樣用的效果更好,因此除了shouldComponentUpdate,其餘在render函數以前的全部函數(componentWillMount,componentWillReceiveProps,componentWillUpdate)都被getDerivedStateFromProps替代。component

也就是用一個靜態函數getDerivedStateFromProps來取代被deprecate的幾個生命週期函數,就是強制開發者在render以前只作無反作用的操做,並且能作的操做侷限在根據props和state決定新的state對象

React v16.0剛推出的時候,是增長了一個componentDidCatch生命週期函數,這只是一個增量式修改,徹底不影響原有生命週期函數;可是,到了React v16.3,大改動來了,引入了兩個新的生命週期函數。生命週期

新引入了兩個新的生命週期函數:getDerivedStateFromPropsgetSnapshotBeforeUpdate

getDerivedStateFromProps

getDerivedStateFromProps原本(React v16.3中)是隻在建立和更新(由父組件引起部分),若是不是由父組件引起,那麼getDerivedStateFromProps也不會被調用,如自身setState引起或者forceUpdate引起。開發

React v16.3 的生命週期圖get

img

React v16.3

這樣的話理解起來有點亂,在React v16.4中改正了這一點,讓getDerivedStateFromProps不管是Mounting仍是Updating,也不管是由於什麼引發的Updating,所有都會被調用,具體可看React v16.4 的生命週期圖。

React v16.4後的getDerivedStateFromProps

static getDerivedStateFromProps(props, state) 在組件建立時和更新時的render方法以前調用,它應該返回一個對象來更新狀態,或者返回null來不更新任何內容。

getSnapshotBeforeUpdate

getSnapshotBeforeUpdate() 被調用於render以後,能夠讀取但沒法使用DOM。它使您的組件能夠在可能更改以前從DOM捕獲一些信息(例如滾動位置)。今生命週期返回的任何值都將做爲參數傳遞給componentDidUpdate()。

官網給的例子:

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>
    );
  }
相關文章
相關標籤/搜索