React(三)——React組件之生命週期

目錄

1.週期分類

2.掛載階段

2.1constructor

2.2render()

2.3static getDerivedStateFromProps()

2.4componentDidMount()

3.更新階段

3.1static getDerivedStateFromProps()

3.2shouldComponentUpdate()

3.3render()

3.4getSnapshotBeforeUpdate()

3.5componentDidUpdate()

4.卸載階段

4.1componentWillUnmount()

5.錯誤處理

5.1static getDerivedStateFromError()

5.2componentDidCatch()


生命週期

所謂的生命週期就是指某個事物從開始到結束的各個階段,當然在 React.js 中指的是組件從創建到銷燬的過程,React.js 在這個過程中的不同階段調用的函數,通過這些函數,我們可以更加精確的對組件進行控制,前面我們一直在使用的 render 函數其實就是組件生命週期渲染階段執行的函數

1.週期分類

React.js 爲組件的生命週期劃分了四個不同的階段

  • 掛載階段

  • 更新階段

  • 卸載階段

  • 錯誤處理

不同的階段又會對應着一些不同的函數

參考:http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/

 

2.掛載階段

掛載階段是指組件創建到渲染到頁面的過程,這個過程提供了四個不同的函數

  • constructor()

  • render()

  • static getDerivedStateFromProps()

  • componentDidMount()

2.1constructor

constructor(props)

類的構造函數,也是組件初始化函數,一般情況下,我們會在這個階段做一些初始化的工作

  • 初始化 state

  • 處理事件綁定函數的 this

2.2render()

render 方法是 Class 組件必須實現的方法

2.3static getDerivedStateFromProps()

static getDerivedStateFromProps(props, state)

該方法會在 render 方法之前調用,無論是掛載階段還是更新階段,它的存在只有一個目的:讓組件在 props 變化時更新 state

案例:郵件發送-收件人選擇

2.4componentDidMount()

componentDidMount()

在組件掛載後(render 的內容插入 DOM 樹中)調用。通常在這個階段,我們可以:

  • 操作 DOM 節點

  • 發送請求

3.更新階段

更新階段是指組件重新渲染的過程,組件 state 的更新(調用 setState())和父組件渲染都會觸發

  • static getDerivedStateFromProps()

  • shouldComponentUpdate()

  • render()

  • getSnapshotBeforeUpdate()

  • componentDidUpdate()

3.1static getDerivedStateFromProps()

同掛載階段,更新階段也會觸發該生命週期函數

3.2shouldComponentUpdate()

shouldComponentUpdate(nextProps, nextState)

發生在更新階段,getDerivedStateFromProps 之後,render 之前,該函數會返回一個布爾值,決定了後續是否執行 render,首次渲染不會調用該函數

import React from 'react';
import Child from './Child';
​
export default class ShouldComponentUpdateComponent extends React.Component {
    constructor(...args) {
        super(...args);
        this.state = {
            n: 1,
        }
    }
  
    render() {
        return(
            <div>
                    <h2 onClick={e=> {
                    this.setState({n: this.state.n + 1})
                }}>n: {this.state.n}</h2>
                <Child value={this.state.n} />
              </div>
        )
    }
}
import React from 'react';
​
export default class Child extends React.Component {
​
    constructor(...props) {
        super(...props);
​
        this.state = {
            value: this.props.value
        };
    }
  
    shouldComponentUpdate(nextProps, nextState) {
        return this.state.value !== nextState.value;
    }
  
    render() {
        console.log('render');
        return(
            <div>
                value: {this.state.value}
                <button onClick={e=>{
                    this.setState({
                        value: this.state.value + 1
                    })
                }}>+</button>
            </div>
        );
    }
}

此方法僅作爲性能優化的方式而存在,不要企圖依靠此方法來“阻止”渲染,因爲可能會產生一些問題。其次,在 React.js 中本來對渲染已經做了必要的優化了,所以通過該函數本質上不能帶來特別大的明顯提升,且容易增加組件的複雜性,變得難以維護,除非確定使用它能爲當前組件帶來顯著的性能提升

官方後期也會更改該方法的特性,即使返回 false 仍可能會重新渲染組件

不推薦濫用該函數

3.3render()

同上

3.4getSnapshotBeforeUpdate()

getSnapshotBeforeUpdate(prevProps, prevState)

該方法在 render() 之後,但是在輸出到 DOM 之前執行,用來獲取渲染之前的快照。當我們想在當前一次更新前獲取上次的 DOM 狀態,可以在這裏進行處理,該函數的返回值將作爲參數傳遞給下個生命週期函數 componentDidUpdate

該函數並不常用。

3.5componentDidUpdate()

componentDidUpdate(prevProps, prevState, snapshot)

該函數會在 DOM 更新後立即調用,首次渲染不會調用該方法。我們可以在這個函數中對渲染後的 DOM 進行操作

4.卸載階段

當組件從 DOM 中移除時會調用如下方法

  • componentWillUnmount()

4.1componentWillUnmount()

componentWillUnmount()

該方法會在組件卸載及銷燬前調用,我們可以在這裏做一些清理工作,如:組件內的定時器、未完成的請求等

5.錯誤處理

當渲染過程,生命週期,或子組件的構造函數中拋出錯誤時,會調用如下方法

  • static getDerivedStateFromError()

  • componentDidCatch()

5.1static getDerivedStateFromError()

static getDerivedStateFromError(error)

該方法用來獲取子組件拋出的錯誤,返回值是一個對象,該對象被存儲在 state 中,在後續的 render 方法中就可以根據這個對象的值來進行處理,如:顯示不同的 UI

class ErrorBoundary extends React.Component {
      constructor(props) {
      super(props);
      this.state = { hasError: false };
  }
​
  static getDerivedStateFromError(error) {
      return { hasError: true };
  }
​
  render() {
      if (this.state.hasError) {
            return <div>出錯了</div>;
      }
      return this.props.children;
  }
}

5.2componentDidCatch()

componentDidCatch(error, info)

該方法與 getDerivedStateFromError() 類似,但是也有不同的地方:

  • 該方法會有一個記錄詳細錯誤堆棧信息的 info 參數

  • 該方法可以執行一些額外的操作:打印錯誤、上報錯誤信息……

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章