React 16.4 的生命周期圖
早期React生命周期圖
從圖中,我們看到了一些變化
廢棄的三個生命周期函數 componentWillMount,componentWillReceiveProps,componentWillUpdate。可以理解為帶有Will都被干掉了。
新增方法:
1.getDerivedStateFromProps
React生命周期的命名一直都是非常語意話的,這個生命周期的意思就是從props中獲取State。
這個函數是為了替代compontWillReceiveProps存在的,所以在你需要使用componentWillReceiveProps的時候,就可以考慮getDerivedStateFromProps來進行替代 了。
這個函數在每次re-render之前被調用,這意味著你的props沒有任何變化,而父state發生了變化,導致子組件發生了re-render,這個生命周期函數依然會被調用。
它是一個靜態函數,也就是這個函數不能通過this訪問到class屬性,也并不推薦直接訪問屬性。而是通過參數傳遞提供的nextProps以及preState來進行判斷,根據傳人的props來映射state。getDerivedStateFromProps?總是需要返回值,返回?null?表示不更新,而componentWillReceiveProps?需要調用setState去更新視圖數據
static getDerivedStateFromProps(nextProps, prevState) {
? //根據nextProps和prevState計算出預期的狀態改變,返回結果會被送給setState
}
2.getSnapshotBeforeUpdate
該函數會在render之后執行,而執行之時DOM元素還沒有被更新,給了一個機會去獲取DOM信息,計算得到一個snapshot,這個snapshot會作為componentDidUpdate的第三個參數傳入。
getSnapshotBeforeUpdate(prevProps, prevState) {
??? console.log('#enter getSnapshotBeforeUpdate');
??? return 'foo';
? }
? componentDidUpdate(prevProps, prevState, snapshot) {
??? console.log('#enter componentDidUpdate snapshot = ', snapshot);
? }
React生命周期的三個階段
掛載階段
static getDerivedStateFromProps()
更新階段
static getDerivedStateFromProps()
注意:下述方法即將過時,在新代碼中應該避免使用他們:
UNSAFE_componentWillReceiveProps()
卸載階段
錯誤處理
當渲染過程,生命周期,或子組件的構造函數中拋出錯誤時,會調用如下方法:
static getDerivedStateFromError()
其他 APIs
用來設置state的值
在16.3開始,議使用setState的異步函數寫法,如:原先我們在使用的時候直接進行賦值:
this.setState({inputValue: e.target.value});
而是使用
This.setState(()=>{ Return { inputValue: value};})
異步方法中,該方法提供了一個回調函數,通過該回調函數,可以確保只有等到setState觸法完成之后,才會執行執行回調
this.setState((prevState, nextState)=>{ ... }, callback);
調用forceUpdate()的時候,將會跳過ShouldComponent而直接render組件父組件中調用forceUpdate亦會導致自組件的生命周期被觸發包括(componentDidUpdate)
為何移除 componentWillUpdate
大多數開發者使用 componentWillUpdate 的場景是配合 componentDidUpdate,分別獲取 rerender 前后的視圖狀態,進行必要的處理。但隨著 React 新的 suspense、time slicing、異步渲染等機制的到來,render 過程可以被分割成多次完成,還可以被暫停甚至回溯,這導致 componentWillUpdate 和 componentDidUpdate 執行前后可能會間隔很長時間,足夠使用戶進行交互操作更改當前組件的狀態,這樣可能會導致難以追蹤的 BUG。
React 新增的 getSnapshotBeforeUpdate 方法就是為了解決上述問題,因為 getSnapshotBeforeUpdate 方法是在 componentWillUpdate 后(如果存在的話),在 React 真正更改 DOM 前調用的,它獲取到組件狀態信息更加可靠。
除此之外,getSnapshotBeforeUpdate 還有一個十分明顯的好處:它調用的結果會作為第三個參數傳入 componentDidUpdate,避免了 componentWillUpdate 和 componentDidUpdate 配合使用時將組件臨時的狀態數據存在組件實例上浪費內存,getSnapshotBeforeUpdate 返回的數據在 componentDidUpdate 中用完即被銷毀,效率更高。
問題:
1.為什么componentWillMount被刪掉componentDidMount還在?
componentDidMount()?會在組件掛載后(插入 DOM 樹中)立即調用。依賴于 DOM 節點的初始化應該放在這里。如需通過網絡請求獲取數據,此處是實例化請求的好地方。