來學 React 吧之四_Class component 介紹及與 Function component 的差異


Posted by Christy on 2021-11-10

本文為學習 React 16.8 版本以前的 class component 相關知識,以及 class vs fn component 的差異;內有基礎介紹、如何應用、class component 的生命週期以及兩者概念差異比較

一、什麼是 class component?

在 React 16.8 版本之前,沒有 hook,因此大家都用 class 寫 component,在這裡的學習目的是,有些舊的專案還是有可能會看到這個語法,建議知道一下比較好。

要怎麼寫?

1. 需要 ES6 class and this 的先備知識

寫一個名字叫 Button 的 class component

class Button extends React.Component {
  render() {
    const { onClick, children } = this.props;
    return <button onClick={onClick}>{children}</button>;
  }
}

2. 通常出現這個錯誤都代表 this 的值有錯:

"TypeError: Cannot read property 'props' of undefined"

解法就是:

a. 利用 constructor 把 this 的值綁定 .bind()

b. 寫成類似箭頭函式的寫法(長得很像,但有點不一樣)

參考資料:

Arrow functions in React

React Quick Tip: Use Class Properties and Arrow Functions to Avoid Binding this to Methods

React | 那個在 Class Component 中的 Arrow function (箭頭函式)

二、Class component 的生命週期

以 counter 為例解釋 Class component 的生命週期

import React from 'react';

export default class Counter extends React.Component {
  constructor(props) {
    super(props);

    // 唯一可以指定初始值的地方只有在 constructor
    // 其他地方都要用 setState()
    this.state = {
      counter: 1,
    };
    console.log('constructor')
  }

  // React 內建的生命週期 method
  componentDidMount() {
    console.log('did mount', this.state)
  }

  componentDidUpdate(prevProps, prevState) {
    console.log('prevState:', prevState)
    console.log('update!')
  }

  componentWillUnmount() {
    console.log('unmount')
  }

  handleClick = () => {
    this.setState({
      counter: this.state.counter + 1,
    });
  };

  render() {
    const { counter } = this.state;
    console.log('render')
    return (
      <div>
        <button onClick={this.handleClick}>+1</button>
        counter: {counter}
      </div>
    );
  }
}

1. 生命週期裡面有幾個 React 的 method,因為是 React 內建,所以 this 的值已經設定好了。

a. componentDidMount(): component mount 以後執行

b. componentWillUnmount(): component unmount 之前(意指把 component 從畫面上去除,不 render 它的時候)

c. componentDidUpdate(): component update 之後,會給你前一次的 props & state 兩個參數

2. 執行上面的程式碼,會依序印出什麼呢?

a. 畫面上有一個 counter 計數器,當第一次 render 時,會先印出 constructor -> render -> did mount;did mount 只會印出一次,就是 component 放到畫面上時。

當按下 +1 的按鈕時(state 改變時),會印出 render -> prevState -> update!

unmount 只有在 component 不被 render 時才會出現。

PS: 有一些 method 已經被 React deprecated 例如 componentWillMount() 就不建議使用了。

b. shouldComponentUpdate() 介紹

b.1 當某些條件發生時,禁止 React update,跟 React 效能優化比較有關

// 如果回傳 false 就不會 update
shouldComponentUpdate(nextProps, nextState) {
  if (nextState.counter > 5) return false;
  return true;
}

b.2 或用 PureComponent 一開始在這裡寫成這樣:
export default class Counter extends React.PureComponent,React 會自動幫你優化

b.3 react class component lifecycle:

圖片來源

3. fn component & class component 的不同

影片在 FE302 > Function component vs Class component > Class component 的生命週期 11'59"

a. class component 所用的方式是「每個生命週期都有對應的 method,要做事時就把東西寫在裡面」

b. fn component 什麼東西都寫在 fn 裡面,每次執行都會 render 一次,生命週期的方式改用成 useEffect(),fn component 這裡有介紹:React.Component










Related Posts

【Day04】元件

【Day04】元件

用 Express & Sequelize 做一個餐廳網站

用 Express & Sequelize 做一個餐廳網站

npm

npm


Comments