React生命周期
「16版本以前的:」
生命周期流程圖
組件從生成到被掛在到頁面上的一系列過程
根據流程圖打印的執行順序圖:
流程講解:
初始化流程
start | 開始創建組件 | 在這個周期中做的事情 |
---|---|---|
檢查 | 檢查組件中是否有默認的屬性、是否有屬性校驗 | |
constructor | 開始執行constructor構造函數 (👩🏫講解:constructor是生命周期的一部分。react.component就是一個抽象類,官方文檔就是這么定義的。) |
構造類。在這里可以寫一些狀態 可以進行ajax數據請求 |
componentWillMount | 執行componentWillMount生命周期函數。此時組件即將掛載到頁面上。 (類似vue的beforeMounte) 會有關於componentWillMount更名的信息提示 ![]() |
可以進行ajax請求 「(但是react官方不建議。因為可能后期會使用react Native時會與之發生沖突。而且官方特強硬的把這個周期函數給移除了。16.3版本以后移除了)」 也可以setState一下 |
render | 執行render函數渲染頁面。 | 沒必要進行ajax請求 「不能調用setState,否則會死循環。因為setState會觸發shouldComponentUpdate,觸發后如果返回true,又會走到render里。所以,render里只做數據渲染、展示就行,別進行setState」 |
componentDidMount | 執行componentDidMount生命周期函數。此時組件已經被掛載到頁面中。 (類似vue的mounted) |
可以發送ajax、設置狀態(setState)的「最好的地方」 |
組件運行流程
state值被改變
state被更改 | 組間運行中,state被更改 | |
---|---|---|
進行提問 是否繼續? |
觸發「shouldComponentUpdate」函數。提問組件是否要進行更新。 該函數接收兩個參數:nextProps、nextStates 該函數需要返回布爾值來「回答」是否更新: return false不更改 - 流程回到state被更改前。 return true進行更改 - state更改,流程繼續。 |
可以在參數里邊知道將要更新的值 「可以比較值,發現需要更改的值與更改前后一致時,返回false,不觸發更新。」 因為react沒有vue那么智能,不知道要更改的內容是否真的發生了改變。「只要setState就會觸發更新、只要觸發了更新就會走剩下的流程。還會去對比虛擬dom、耗費性能 。其內部的子組件的生命周期也會觸發一遍。」 shouldComponentUpdate(nextProps,nextStates){ return nextStates.count !== this.state.count } |
【回答】:是 | ||
componentWillUpdate | 執行conponentWillUpdate生命周期函數。告知組件即將開始進行更新。 | 千萬不能設置狀態,因為會又回到shouldComponentUpdate的死循環中。 沒必要做ajax請求,即使做了也不能重新setState 基本上沒什么用 |
render | 組間更新完畢,執行render函數重新渲染頁面。 | (同上邊的render。) |
componentDidUpdate | 執行componentDidUpdate生命周期函數。告知組件更新並渲染完畢。此時更新過的組件已經渲染到頁面中。 | 千萬不能設置狀態,因為會又回到shouldComponentUpdate的死循環中。 沒必要做ajax請求,即使做了也不能重新setState 基本上沒什么用 |
【往復】:回到組件運行狀態(等待) |
props改變,重新render
props屬性是從父組件傳過來的。當父組件改變了傳遞給子組件的數據時,子組件內部就會觸發該函數。
以下流程發生在子組件內部:子組件內部
componentWillReceiveProps | 執行componentWillReciveProps生命周期函數。告知父組件改變了props的值。 接受參數:nextProps 初始化不執行,只有當props改變時才會執行 |
可以進行狀態的設置: 因為其可以接受一個參數nextProps,然后把參數的屬性值setState到this.state身上 可以發送ajax請求: 同上 「但是官方不建議這么做,認為是不合理的。所以在16.3以后的版本中移除了,該函數不能使用了。」 |
---|---|---|
【循環】:重走state值被更改的流程如下: | ||
進行提問 是否繼續? |
觸發shouldComponentUpdate函數。提問組件是否要進行更新。 該函數接收兩個參數:nextProps、nextStates 該函數需要返回布爾值來「回答」是否更新: return false不更改 - 流程回到state被更改前。 return true進行更改 - state更改,流程繼續。 |
|
【回答】:是 | ||
componentWillUpdate | 執行conponentWillUpdate生命周期函數。告知組件即將開始進行更新。 | 「在16.3以后的版本中移除了」 |
render | 組間更新完畢,執行render函數重新渲染頁面。 | |
componentDidUpdate | 執行componentDidUpdate生命周期函數。告知組件更新並渲染完畢。此時更新過的組件已經渲染到頁面中。 | |
【往復】:回到組件運行狀態(等待) |
組件被移除、銷毀
componentWillUnmount | 執行componentWillUnmount生命周期函數。告知即將銷毀組件。 | 銷毀組件前,可以先告知用戶之類的。 |
---|---|---|
【銷毀】:組件銷毀完畢。 |
代碼演示:
見github (https://github.com/xingorg1/JuFengGuo/tree/master/advanceCourse/react/3-react_lifecycle/src/components/before_16.3)
生命周期鈎子函數的功能:
每個生命周期都可以用來干什么?詳見上述表格中各對應列
「16.3版本以后的:」
「基本把‘xxWillxxx’等,帶“Will”的鈎子函數都刪掉了」
生命周期流程圖
組件從生成到被掛在到頁面上的一系列過程。
根據流程圖打印的執行順序圖:
流程講解:
初始化流程
start | 開始創建組件 | 在這個周期中做的事情 |
---|---|---|
檢查 | 檢查組件中是否有默認的屬性、是否有屬性校驗 | |
constructor | 開始執行constructor構造函數 (👩🏫講解:constructor是生命周期的一部分。react.component就是一個抽象類,官方文檔就是這么定義的。) |
構造類。在這里可以寫一些狀態 可以進行ajax數據請求(要不要在constructor里獲取數據) |
static getDerivedStateFromProps(props,state) | 執行一個靜態的方法。從屬性中去獲得狀態**。** 「初始化就會執行」 「這樣,更改state和更改props,就不會走兩套路線了,而是都走這一個。」 「必須返回一個state的對象。否則報錯如下」 Warning: Father.getDerivedStateFromProps(): A valid state object (or null) must be returned. You have returned undefined. 「return的返回值,就會放到組件的state狀態中」 參數:props、state,就是當前組件的屬性狀態值和屬性值 |
|
render | 執行render函數渲染頁面。 | 沒必要進行ajax請求 「不能調用setState,否則會死循環。因為setState會觸發shouldComponentUpdate,觸發后如果返回true,又會走到render里。所以,render里只做數據渲染、展示就行,別進行setState」 |
componentDidMount | 執行componentDidMount生命周期函數。此時組件已經被掛載到頁面中。 (類似vue的mounted) |
可以發送ajax、設置狀態(setState)的「最好的地方」 |
組件運行流程
state 或 props其中任意一個被改變后
static getDerivedStateFromProps(props,state) | state或props更改,都會執行這個靜態的方法。從屬性中去獲得狀態**。** 「這樣,更改state和更改props,就不會走兩套路線了,而是都走這一個。」 「必須返回一個state的對象。否則報錯如下」 Warning: Father.getDerivedStateFromProps(): A valid state object (or null) must be returned. You have returned undefined. |
|
---|---|---|
進行提問 是否繼續? |
觸發shouldComponentUpdate函數。提問組件是否要進行更新。 該函數接收兩個參數:nextProps、nextStates 該函數需要返回布爾值來「回答」是否更新: return false不更改 - 流程回到state被更改前。 return true進行更改 - state更改,流程繼續。 |
可以在參數里邊知道將要更新的值 「可以比較值,發現需要更改的值與更改前后一致時,返回false,不觸發更新。」 因為react沒有vue那么智能,不知道要更改的內容是否真的發生了改變。「只要setState就會觸發更新、只要觸發了更新就會走剩下的流程。還會去對比虛擬dom、耗費性能 。其內部的子組件的生命周期也會觸發一遍。」 shouldComponentUpdate(nextProps,nextStates){ return nextStates.count !== this.state.count } |
【回答】:是 | ||
render | 組件更新完畢,執行render函數重新渲染頁面。 | (同上邊的render。) |
getSnapshotBeforeUpdate(prevProps,prevState) | 執行這個函數,獲取之前狀態的一個快照。 「需要有返回值。其返回值供下邊的鈎子函數componentDidUpdate中接受並使用。」 ![]() 「所以該函數必須和componentDidUpdate函數寫在一起。」 |
|
componentDidUpdate | 執行componentDidUpdate生命周期函數。告知組件更新並渲染完畢。此時更新過的組件已經渲染到頁面中。 「可支持接受三個參數。分別是prevProps、prevState、snapShot」 「其中,snapShot是getSnapshotBeforeUpdate的返回值」 ** ![]() |
千萬不能設置狀態,因為會又回到shouldComponentUpdate的死循環中。 沒必要做ajax請求,即使做了也不能重新setState 基本上沒什么用 |
【往復】:回到組件運行狀態(等待) |
組件被移除、銷毀
componentWillUnmount | 執行componentWillUnmount生命周期函數。告知即將銷毀組件。 | |
---|---|---|
【銷毀】:組件銷毀完畢。 |
代碼演示:
見github (https://github.com/xingorg1/JuFengGuo/tree/master/advanceCourse/react/3-react_lifecycle/src/components/after_16.3)
生命周期鈎子函數的功能:
每個生命周期都可以用來干什么?詳見上述表格中各對應列
本文使用 mdnice 排版