文章

React 生命週期(類別組件)

React 生命週期(類別組件)

在 React 的類別組件(Class Components)中,生命週期方法允許我們在組件的不同階段執行特定的代碼。這些方法分為三個主要階段:掛載階段(Mounting)更新階段(Updating)卸載階段(Unmounting)

以下是這些階段和對應的生命週期方法:


1. 掛載階段(Mounting)

掛載階段是組件被創建並添加到 DOM 中的過程。這個階段會觸發一系列生命週期方法,我們可以在這些方法中設置初始狀態或進行 API 請求等操作。

掛載階段的生命週期方法包括:

  • constructor()
  • static getDerivedStateFromProps()
  • render()
  • componentDidMount()

方法詳解:

  1. constructor(props)
    • 時機:這是組件的構造函數,當組件被初始化時第一個調用。
    • 功能:通常用於初始化組件的 state 和綁定事件處理程序(如 this.handleClick = this.handleClick.bind(this))。
    • 範例
      1
      2
      3
      4
      
      constructor(props) {
        super(props);
        this.state = { count: 0 };
      }
      
  2. static getDerivedStateFromProps(nextProps, prevState)
    • 時機:在每次渲染之前(包括初始化渲染和後續更新)調用,用於從 props 派生 state
    • 功能:可以根據新的 props 更新狀態。這是一個靜態方法,因此無法訪問 this
    • 範例
      1
      2
      3
      4
      5
      6
      
      static getDerivedStateFromProps(nextProps, prevState) {
        if (nextProps.value !== prevState.value) {
          return { value: nextProps.value };
        }
        return null;
      }
      
  3. render()
    • 時機:這是唯一一個必須實現的方法,每當組件的 stateprops 發生改變時會觸發。
    • 功能:返回一個 React 元素,描述 UI 如何展示。這個方法應該保持純粹,不應在此進行數據請求或狀態更新。
    • 範例
      1
      2
      3
      
      render() {
        return <div>{this.state.count}</div>;
      }
      
  4. componentDidMount()
    • 時機:組件第一次被渲染並已經掛載到 DOM 之後執行。
    • 功能:在這裡你可以進行數據請求、DOM 操作、設定計時器等副作用操作。
    • 範例
      1
      2
      3
      4
      5
      
      componentDidMount() {
        fetch('/api/data')
          .then(response => response.json())
          .then(data => this.setState({ data }));
      }
      

2. 更新階段(Updating)

當組件的 propsstate 發生變化時,組件會進入更新階段。這個階段的生命週期方法允許你在組件重新渲染之前、渲染之後或在渲染過程中對組件進行操作。

更新階段的生命週期方法包括:

  • static getDerivedStateFromProps()
  • shouldComponentUpdate()
  • render()
  • getSnapshotBeforeUpdate()
  • componentDidUpdate()

方法詳解:

  1. shouldComponentUpdate(nextProps, nextState)
    • 時機:在重新渲染之前(每次 propsstate 發生改變時)執行。
    • 功能:返回一個布林值,決定組件是否應該重新渲染。默認返回 true。你可以根據條件優化組件,避免不必要的渲染。
    • 範例
      1
      2
      3
      
      shouldComponentUpdate(nextProps, nextState) {
        return nextState.count !== this.state.count;
      }
      
  2. getSnapshotBeforeUpdate(prevProps, prevState)
    • 時機:在更新之前,且在 render() 之後(更新後 DOM 尚未變更)調用。
    • 功能:允許你獲取更新之前的 DOM 狀態,比如滾動位置等。返回的值會作為 componentDidUpdate() 的第三個參數。
    • 範例
      1
      2
      3
      4
      5
      6
      
      getSnapshotBeforeUpdate(prevProps, prevState) {
        if (prevProps.list.length < this.props.list.length) {
          return this.listEnd.scrollHeight;
        }
        return null;
      }
      
  3. componentDidUpdate(prevProps, prevState, snapshot)
    • 時機:組件更新並重新渲染到 DOM 之後執行。
    • 功能:可以在這裡進行 DOM 操作或發起基於更新後數據的 API 請求。第三個參數 snapshotgetSnapshotBeforeUpdate() 返回的值。
    • 範例
      1
      2
      3
      4
      5
      
      componentDidUpdate(prevProps, prevState, snapshot) {
        if (snapshot !== null) {
          this.listEnd.scrollTop = this.listEnd.scrollHeight - snapshot;
        }
      }
      

3. 卸載階段(Unmounting)

當組件即將從 DOM 中移除時,會進入卸載階段。在這個階段,你可以進行清理工作,例如移除事件監聽器、取消計時器等。

卸載階段的生命週期方法包括:

  • componentWillUnmount()

方法詳解:

  1. componentWillUnmount()
    • 時機:當組件即將從 DOM 中移除時調用。
    • 功能:你可以在這裡執行清理工作,比如移除事件監聽器、取消 API 請求或計時器。
    • 範例
      1
      2
      3
      
      componentWillUnmount() {
        clearInterval(this.timerID);
      }
      

4. React 16.x 之後的變化

自 React 16.3 版本後,React 生命週期方法發生了變化。一些方法被標記為不建議使用(Deprecated),例如 componentWillMount()componentWillReceiveProps()componentWillUpdate(),這些方法會被逐步淘汰,並由新的方法(如 getDerivedStateFromProps()getSnapshotBeforeUpdate())取代。

已淘汰的方法

  • componentWillMount()
  • componentWillReceiveProps()
  • componentWillUpdate()

這些方法仍然可以使用,但 React 會給出警告,鼓勵使用新的 API。


總結

React 的生命週期方法可以幫助開發者在組件的不同階段控制行為。根據組件的掛載、更新或卸載階段,開發者可以在合適的生命週期方法中進行數據請求、狀態更新或清理工作。隨著 React 版本的更新,某些生命週期方法已被替換,因此建議使用最新的 API 來保持代碼的前瞻性和可維護性。

本文章以 CC BY 4.0 授權