hamburger-icon hamburger-icon

React:Class-based & Functional Component

|

2023/03/25

|

Dev Tech

|

johch3n611u

這個作者很懶,什麼都沒留下...

Class-based Functional Component
  • 需繼承 React.Component
  • 具有生命週期,可以針對某些情境決定是否渲染
  • 需要在設置 State ( Stateful Component )
  • 每次都可以拿到最新的 this.props,因為 this 隨時都在變化
  • 需要比較多 JS 的背景知識
  • 不能使用 Hook
  • 需定義 render() 並將要渲染到畫面上的內容 return
  • this 必須在一開始被指向才可以使用
  • 2019 年 v16.8 Hooks 釋出後的主流寫法
  • 單純只是一個普通的 JavaScript 函式
  • 感覺很像 Vue 3
  • 生命週期要透過 useEffect Hook
  • 無狀態組件 State(Stateless)要透過 useState Hook
  • 可以用 Arrow Function 宣告或是一般的 Function
  • 編譯快程式碼更少,不用將 Class 轉換成 ES5,不繼承 React Component
  • 閉包的特性 props 會一直是原本傳進來的那個,而不會跟著外層狀態更新,必須透過 Hook 管控狀態
  • 閉包的特性 this 會直接綁定元件本身
  • 分離容器組件和展示組件會變得更容易

Class-based

class Car extends React.Component { 
  constructor() { 
    super(props); // 要在 constructor 中使用才需要 super
    this.state = { name: "miaHsu" };
    this.handleInput = this.handleInput.bind(this);
  }

  handleInput(e) {
    this.setState({ input: e.target.value });
  }

  render() {
    <input onChange={handleInput} value={this.state.name} />
    <h2>Hi, I am a {this.props.name}!</h2>; // 不需要 super 也可以使用 this.props
  }

  this.setState({name: 'BrainLin'});
}

Functional Component

function Car(props) {
  const [name, setName] = useState("miaHsu");

  function handleInput(e) {
    setName(e.target.value);
  }

  return (
    <div>
      <input onChange={handleInput} value={name} />
      <h2>Hi, I am a {props.name}!</h2>
      <button onClick={() => setName('BrainLin')}>Change Name</button>
    </div>
  );
}

let Car = (props) => {
  return <h2>Hi, I am a {props.name}!</h2>;
}

Functional Programming

一種程式設計風格,避免改變狀態和可變數據,使用遞歸和高階函數,實現代碼簡潔、易於測試、避免產生錯誤

// No Functional Programming
const arr = [1, 2, 3, 4, 5, 6];

let result = [];
for (let i = 0; i < arr.length; i++) {
  if (arr[i] % 2 === 0) {
    result.push(arr[i] * 2);
  }
}

// Functional Programming
result = arr.filter((x) => x % 2 === 0).map((x) => x * 2);

Hooks

[React Hook 筆記] Custom Hooks 之打造自己的 Hook

  • Hook:React 16.8版本引入的一個新特性,提供了在 Functional Component 使用 State、Lifecycle 管理不同的狀態或實現不同的功能的統一稱呼;

  • Custom Hook / Hook:其實就只是 JS Function 抽出來利於重覆利用,一樣可以使用 React 就有提供的 Hooks,但必須以 「 use 」為開頭命名的 JavaScript function,並在最後 回傳的是一些資料或改變資料的方法。

  • Hook 方法不能在條件式、迴圈或嵌套函式中呼叫:這是因為 Hook 的調用順序是有要求的,如果在條件式、迴圈或嵌套函式中呼叫 Hook,可能會導致 Hook 調用的順序錯誤,從而導致組件的行為出現問題。

  • 透過 use() 產出的變數和方法,可以在判斷式內使用:這是因為在 React 中,為了避免在渲染期間過多地重新創建對象,Hook 中返回的狀態和方法通常是經過優化的,因此可以在判斷式內使用,而不會導致渲染問題。

import { useState, useEffect } from 'react';

function useLocalStorage(key, initialValue) {
  // 定義狀態為 value 的變數
  const [value, setValue] = useState(() => {
    // 從 localStorage 中獲取對應 key 的值
    const item = window.localStorage.getItem(key);
    // 如果 localStorage 中有值,返回該值,否則返回初始值
    return item ? JSON.parse(item) : initialValue;
  });

  useEffect(() => {
    // 在每次 value 改變時,將對應 key 的值更新到 localStorage 中
    window.localStorage.setItem(key, JSON.stringify(value));
  }, [key, value]);

  // 返回一個包含 value 和 setValue 的對象
  return { value, setValue };
}

Pure Component / React.memo ( HOC ) Higher Order Component

https://ithelp.ithome.com.tw/articles/10241071

import React, { memo } from 'react';

function MyComponent(props) {
    return (
      <div>
        <h2>{props.title}</h2>
        <p>{props.content}</p>
      </div>
    );
}

export default memo(MyComponent);

參考