1. 程式人生 > >React 生命周期簡介

React 生命周期簡介

修改 count 避免 efi panel nds 每次 流程 不能

React 中組件的生命周期會經歷如下三個過程:裝載過程、更新過程、卸載過程。
  • 裝載過程:組件實例被創建和插入 DOM 樹的過程;
  • 更新過程:組件被重新渲染的過程;
  • 卸載過程:組件從 DOM 樹中刪除的過程。

註意:裝載過程與卸載過程在組件的生命周期中只會執行一次,更新過程可以多次執行。

在這三個過程中,分別依次調用了組件的生命周期函數。

React 組件生命周期總體流程圖如下:

技術分享圖片

一、裝載過程

在這個過程中組件被創建,裝載過程在組件的生命周期中只會被執行一次,調用的生命周期函數有:

  • defaultProps / getDefaultProps()
  • constructor() / getInitialState()
  • componentWillMount()
  • render()
  • conponentDidMount()

1、defaultProps:

組件類的一個靜態屬性,嚴格來講這裏不屬於組件的生命周期的一部分,用於設置組件 props 的默認值。

  1. class Counter extends Component {
  2. static defaultProps = {
  3. count: 0,
  4. };
  5. render() {
  6. return (
  7. <div>當前值為:{this.props.count}</div>
  8. );
  9. }
  10. };

在調用組件時如果未設置 props.count,這樣 props.count === undefined , 其將被設置默認為 0 :

  1. render() {
  2. return <Counter /> ; // 渲染後顯示為 0
  3. }

如果調用組件時設置 props.count={null} , 這樣渲染出來為 null :

  1. render() {
  2. return <Counter count={null} /> ; // 渲染後顯示為 null
  3. }

他是在執行 React 的 createElement() 時去獲取並賦值給 props 的,發生在組件實例化之前。

2、constructor

constructor 是 ES6 中 class 的構造函數,組件初始化調用的,所以它在組件生命周期函數中最先執行,這裏主要做下面兩件事情:

  • 初始化組件的 state。 它是組件初始化實例時最先執行的一個函數,因此在這裏初始化 state ;
  • 方法的綁定。在 ES6 語法下,類的每個成員函數在執行時的 this 指向並不是和類的實例自動綁定的, 而構造函數中,this指向就是當前組件實例,為了方便將來調用,往往在構造函數中將組件實例的函數使用 bind(this) 這種方式,讓當前實例中的函數調用時,this 始終是指向當前組件實例。
  1. class Counter extends Component {
  2. // 設置默認 props 的值
  3. static defaultProps = {
  4. count: 0,
  5. };
  6. // 構造函數 construcor
  7. constructor(props) {
  8. super(props);
  9. this.state = {
  10. count: 0,
  11. };
  12. this.handleIncrease = this.handleIncrease.bind(this);
  13. }
  14. // 點擊增加1
  15. handleIncrease(){
  16. let addCounter = this.state.counter;
  17. this.setState({
  18. counter: addCounter + 1
  19. })
  20. }
  21. render() {
  22. return (
  23. <div>
  24. 當前 props 值為:{this.props.count}
  25. <br />
  26. 當前 state 值為:{this.state.counter}
  27. <button onClick={this.handleIncrease}>點擊增加</button>
  28. </div>
  29. );
  30. }
  31. };

3、componentWillMount

準備裝載組件。它在組件實例化並初始化數據完成以後,組件 render() 之前調用。

官方文檔說避免在該方法中引入任何的副作用或訂閱,所以我們不建議在此生命周期函數內獲取數據或修改 state; 如果有需求在 render() 前一定要修改 state,最好是在 constructor 裏進行。

4、render

確定需要更新組件時調用 render,根據 diff 算法,渲染界面,生成需要更新的虛擬 DOM 數據。它並不做實際的渲染動作,只是返回了一個 JSX 描述結構,最終是由 React 來操作渲染過程。

render 函數是 React 組件中最重要的函數,一個組件中可以沒有其他的生命周期函數,但一定要有 render 函數,如果一個組件沒有東西可呈現,這個組件的 render 函數定義返回 null 或 false;

render() 是一個純函數,所以在此聲明周期內不能 setState。

5、componentDidMount

在組件裝載後調用。這時已經生成了真實的 DOM 節點。

在這個函數中我們可以獲取數據,改變狀態,直接改變 DOM 等操作。

註意:並不是在調用 render() 函數之後立即調用了此函數,調用 render() 函數只是返回了一個 JSX 對象供 React 調用決定如何渲染,在 React 庫把所有組件渲染完成再完成裝載,這時才會依次調用各個組件的 componentDidMount 函數,表示這個組件已經掛載到 DOM 上了。

以上裝載過程的生命周期函數只會執行一次

二、更新過程

更新過程中依次執行的生命周期函數有:

  • componentWillReceiveProps
  • shouldComponentUpdate
  • componentWillUpdate
  • render
  • componentDidUpdate

並不是每次更新都會依次調用以上全部函數,會根據不同的變化依次執行相關的函數。

1、componentWillReceiveProps(nextProps)

子組件的 props 發生改變及父組件的 render 函數被調用都會觸發子組件的此函數。我們可以根據 nextProps 同步本地的 state,但最好要先比較 this.props 與 nextPorps 在做操作。
本組件中通過 this.setState 方法觸發的更新不會觸發此函數。

2、shouldComponentUpdate(nextProps, nextState)

當組件接收到新的 props 和 state 改變的話,都會觸發調用,返回 Boolean,默認返回的是 true。
返回 true 繼續進行下面的生命周期函數;返回 false 不更新組件。
這個組件中不允許改變 state。
我們可以利用此特點來優化項目,避免不必要的渲染,提高性能。

  1. shouldComponentUpdate(nextProps, nextState) {
  2. return this.props.count !== nextProps.count || this.state.counter !== nextState.counter;
  3. }

3、componentWillUpdate

在 shouldComponentUpdate 函數返回 true 時,會依次調用 componentWillUpdate、render 和 componentDidUpdate 函數。
此函數內不可以改變 state,如果需要更新狀態,請在 componentWillReceiveProps 中調用 this.setState()。

4、render
這次 render() 和裝載階段的 render() 沒有區別,只不過是在不同的階段調用。

前一個 render 是在組件第一次加載時調用的,也就是初次渲染;
後一個 render 是除去第一次之後調用的,也就是再渲染。

5、componentDidUpdate
在組件再次渲染之後調用的。和 componentDidMount 一樣,在這個函數中可以使用 this.refs 獲取真實 DOM。

此函數內不可以改變 state

三、卸載階段

componentWillUnmount

當組件要被從界面上移除的時候,就會調用。
在這個函數中,可以做一些組件相關的清理工作,例如取消計時器、網絡請求等。

代碼 github 地址:https://github.com/mqp0713/react-lifestyle

React 生命周期簡介