文章

React 中的 State 與組件狀態管理

React 中的 State 與組件狀態管理

在 React 中,state 是一個特殊的物件,用來存儲組件的本地狀態。與 props 不同的是,state 是可變的,組件可以通過修改 state 來更新自身的 UI。React 的核心理念之一就是當狀態改變時,React 會自動更新組件的 UI,這使得狀態管理在構建動態應用時至關重要。

1. 什麼是 State?

state 是一個 React 組件內部管理自身數據的機制,這些數據會影響組件的呈現。當 state 發生變化時,React 會重新渲染組件,並更新 UI 以反映最新的狀態。

範例:簡單的計數器組件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import React, { useState } from 'react';

function Counter() {
  // 使用 useState Hook 來設置初始狀態
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>計數: {count}</p>
      <button onClick={() => setCount(count + 1)}>
        增加
      </button>
    </div>
  );
}

export default Counter;

在這個範例中,countstate 的一部分,當 setCount 函數被調用時,count 的值會更新,並且組件會重新渲染顯示新的計數值。


2. 如何使用 State?

React 有兩種主要方式來定義和使用 state

  • 類別組件中的 state
  • 函式組件中的 Hooks(useState)

2.1. 類別組件中的 State

在 React 的類別組件中,我們使用 this.state 來管理狀態。當需要更新狀態時,使用 this.setState() 方法來修改 state,並觸發重新渲染。

範例:類別組件中的 state

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import React, { Component } from 'react';

class Counter extends Component {
  constructor(props) {
    super(props);
    // 設置初始狀態
    this.state = { count: 0 };
  }

  // 定義增加計數的方法
  increment = () => {
    this.setState({ count: this.state.count + 1 });
  };

  render() {
    return (
      <div>
        <p>計數: {this.state.count}</p>
        <button onClick={this.increment}>增加</button>
      </div>
    );
  }
}

export default Counter;

在這裡,this.state 用於存儲組件的狀態,而 this.setState() 用來更新狀態。當 increment 函數被調用時,計數器會增加,並重新渲染顯示新的計數值。


2.2. 函式組件中的 useState Hook

在 React 16.8 之後,我們可以使用 Hooks 來在函式組件中管理狀態。useState 是最常用的 Hook,它允許我們在函式組件中定義和更新狀態。

範例:函式組件中的 useState

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import React, { useState } from 'react';

function Counter() {
  // 使用 useState 來定義 count 狀態,初始值為 0
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>計數: {count}</p>
      <button onClick={() => setCount(count + 1)}>
        增加
      </button>
    </div>
  );
}

export default Counter;

在這裡,我們使用 useState 定義了一個 count 變量,並通過 setCount 函數來更新該變量。每當 setCount 被調用時,React 會重新渲染組件,顯示新的計數值。


3. State 的特點

3.1. 局部性

state 是組件的本地狀態,只有組件自己可以修改自己的狀態。父組件無法直接修改子組件的 state,而需要通過 props 傳遞回調函數來實現間接控制。

3.2. 異步更新

React 中的 setState() 是異步的。這意味著在同一個事件處理程序中多次調用 setState,可能會合併更新,並且你無法立即在 setState 之後獲取更新後的 state 值。

範例:異步更新

1
2
3
4
increment = () => {
  this.setState({ count: this.state.count + 1 });
  console.log(this.state.count); // 這裡的 count 可能還是舊值
};

如果需要基於先前的狀態來進行更新,可以傳入一個回調函數給 setState

範例:基於先前狀態的更新

1
2
3
4
5
increment = () => {
  this.setState((prevState) => ({
    count: prevState.count + 1
  }));
};

3.3. 單向數據流

在 React 中,數據流是單向的,即從父組件流向子組件。父組件可以通過 props 傳遞數據給子組件,而子組件則無法直接修改父組件的 state


4. 多組件之間的狀態共享

有時候,我們需要在多個組件之間共享狀態。此時,我們可以將狀態提升至父組件,然後通過 props 將狀態和更新函數傳遞給子組件。

範例:狀態提升

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function ChildA(props) {
  return <button onClick={props.increment}>Child A 點擊增加</button>;
}

function ChildB(props) {
  return <p>Child B 顯示計數: {props.count}</p>;
}

function ParentComponent() {
  const [count, setCount] = useState(0);

  const increment = () => setCount(count + 1);

  return (
    <div>
      <ChildA increment={increment} />
      <ChildB count={count} />
    </div>
  );
}

在這裡,ParentComponent 共享了它的 count 狀態給兩個子組件,ChildA 通過 increment 函數修改 count,而 ChildB 負責顯示當前的 count


5. useEffect 與 State 變化

state 發生變化時,React 的組件會重新渲染。你可以使用 useEffect Hook 來執行副作用操作(如 API 請求、DOM 操作),並在狀態變化時執行特定的代碼。

範例:使用 useEffect 監聽狀態變化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import React, { useState, useEffect } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    console.log(`當前計數: ${count}`);
  }, [count]); // 當 count 改變時,useEffect 會執行

  return (
    <div>
      <p>計數: {count}</p>
      <button onClick={() => setCount(count + 1)}>增加</button>
    </div>
  );
}

在這個例子中,useEffect 會在 count 變化時執行,這讓我們可以在狀態變化時執行副作用操作。


總結

  • State 是 React 組件內部用來管理數據的機制,當狀態發生變化時,React 會自動重新渲染組件。
  • 類別組件使用 this.statethis.setState 管理狀態,函式組件則通過 useState Hook 來管理。
  • state 是本地的且可變的,父組件無法直接修改子組件的 state
  • 狀態可以提升到父組件中,實現多個組件之間的狀態共享。
  • useEffect Hook 可用來在狀態變化時執行副作用操作。

掌握 React 中的 state 和狀態管理是構建動態、交互式應用程序的關鍵。

本文章以 CC BY 4.0 授權