Jeff的隨手筆記

學習當一個前端工程師

0%

『Day 20』理解 React State 的保存與重置機制

前言

在開發 React 專案的過程中,常常會遇到一些看似神奇的狀況:明明是相同的元件,有時候狀態會保留,有時候卻會重置。這些行為背後其實蘊含著 React 狀態管理的重要原理。今天想跟大家分享我在研讀官方文件時,對於 React 狀態保存機制的一些理解與心得。

React 如何管理狀態?

很多人可能會認為 state 是存在於元件內部的,但實際上,所有的 state 都是由 React 本身來維護的。React 透過「UI 樹中的位置」來建立 state 與元件的關聯,這個設計讓相同的元件在不同位置都能擁有獨立的狀態。

讓我們用一個簡單的例子來說明:

1
2
3
4
5
6
7
8
9
10
function App() {
return (
<div>
<Counter /> // 位置標識: /div/Counter[0]
<div>
<Counter /> // 位置標識: /div/div/Counter[0]
</div>
</div>
);
}

在這個例子中,雖然都是使用 Counter 元件,但因為它們在 UI 樹中的位置不同,React 會為它們分配不同的「位置標識」,讓它們能夠擁有獨立的狀態。

狀態保存的關鍵:位置標識

React 的狀態保存機制主要依賴於 UI 樹中的位置標識。只要元件在 UI 樹中的位置保持不變,其狀態就會被保留。這個機制讓我們能夠在不同的條件渲染中保持狀態的穩定:

1
2
3
4
5
6
7
8
9
10
11
12
13
function App() {
const [isFancy, setIsFancy] = useState(false);

return (
<div>
{isFancy ? (
<Counter isFancy={true} />
) : (
<Counter isFancy={false} />
)}
</div>
);
}

在這個例子中,無論 isFancy 的值如何變化,Counter 的位置都沒有改變,因此它的狀態會被保留。

什麼時候狀態會重置?

了解了狀態保存的機制,我們來看看什麼情況下狀態會被重置:

  1. 元件從 UI 樹中被移除
  2. 在相同位置渲染了不同類型的元件
  3. 元件樹的結構發生變化

避免常見的陷阱

在開發過程中,最常見的一個陷阱就是在元件內部定義子元件:

1
2
3
4
5
6
7
8
// ❌ 不好的寫法
function ParentComponent() {
function ChildComponent() {
const [count, setCount] = useState(0);
return <div>{count}</div>;
}
return <ChildComponent />;
}

這樣的寫法會導致每次父元件重新渲染時,子元件的定義都是全新的,進而導致狀態重置。正確的做法是將元件定義在頂層作用域:

1
2
3
4
5
6
7
8
9
// ✅ 好的寫法
function ChildComponent() {
const [count, setCount] = useState(0);
return <div>{count}</div>;
}

function ParentComponent() {
return <ChildComponent />;
}

總結

理解 React 的狀態管理機制對於開發穩定的應用程式至關重要。記住幾個關鍵點:

  1. React 是透過 UI 樹中的位置來管理狀態
  2. 相同位置的相同元件會保留狀態
  3. 避免在元件內部定義其他元件
  4. 元件的位置變化可能導致狀態重置

希望透過這篇文章的分享,能幫助大家更深入理解 React 的狀態管理機制,寫出更穩定的應用程式。