前言
在剛開始接觸 React 的時候,我常常被 State 的一些特性搞得一頭霧水,特別是一開始當我把它當作普通的 JavaScript 變數使用時,總會遇到一些意想不到的情況,例如:當你想要連續更新好幾次 State 時,卻發現畫面的更新跟你預期的不太一樣?
這是因為 React 的 State 有一個特別的機制,稱為「快照(Snapshot)」。今天就讓我們一起來了解這個概念吧!
什麼是 Snapshot?
可以把 Snapshot(快照) 想像成 React 在某個時間點記錄下的 State 的靜態畫面。每次渲染時,React 都會創建一個快照來保存當前的元件狀態,而這個快照是 不可改變的(Immutable)。
在同一次渲染中,這個快照中的 State 值是不會隨著 setState
的呼叫而改變的,只有在下一次渲染時,快照才會更新為最新的狀態。
假設我們有以下程式碼:
1 | function Counter() { |
當我們點擊按鈕時,你可能會期待 count
會加 3,但實際上它只會加 1!這是因為:
在點擊按鈕時,React 提供了一個當下的快照,此時
count
是 0這三次的
setCount
都是基於這個快照在運作:1
2
3setCount(0 + 1)// 基於快照中的 0
setCount(0 + 1)// 還是基於快照中的 0
setCount(0 + 1)// 依然是基於快照中的 0所以這三次
setCount
其實都是告訴 React:「把 count 設定為 1」React 在下一次渲染時,就會使用最後收到的值,也就是 1
這就像是在拍照一樣,不管你在快門按下後做了什麼動作,照片裡永遠都是按下快門那一刻的畫面。在這裡的快照也是一樣,在這次渲染中,count
的值就固定是 0,不會因為呼叫了 setCount
就立即改變。
React 的渲染機制與快照
React 的渲染機制可以分為以下幾個步驟:
- 調用元件函式,生成新的 JSX 結構。
- 比較新舊的 JSX 結構,計算需要更新的部分。
- 更新畫面,並生成新的 State 快照。
每次渲染時,React 都會創建一個全新的快照,這個快照包含:
- 當前的 State 值
- 事件處理函式
- 當前渲染中使用到的其他變數
非同步操作與 Snapshot
快照特性在非同步操作中也非常重要。例如:
1 | function MessageForm() { |
當我們點擊「延遲傳送」按鈕後:
- React 會記住當下的 message 值
- 即使我們在這 3 秒內修改了輸入框的內容
- 3 秒後跳出的 alert 視窗還是會顯示「哈囉」
這是因為事件處理函式「記住」了它創建時的快照,而非動態追蹤最新的 State 值。
總結
React 中的 state 是由 React 核心統一管理的狀態快照,每次 setState 不是直接修改值,而是觸發重新渲染,產生新的快照,並且在同一次渲染中 state 值保持不變,這樣的設計讓狀態管理更可預測且容易追蹤。