Jeff的隨手筆記

學習當一個前端工程師

0%

『Day 14』React 狀態更新排程概念

前言

在探索 React 的旅程中,我們逐漸掌握了如何運用 useState 來管理元件的狀態。不過,你是否曾遇過明明更新了好幾次狀態,但畫面卻不如預期更新的情況?今天就讓我們一起來看看 React 中狀態更新的一些有趣細節。

React 的批次更新機制

在 React 中,當我們使用 useState hook 更新狀態時,React 會觸發重新渲染。但有趣的是,如果在同一個事件處理中多次呼叫更新函式,React 會很聰明地將這些更新「打包」在一起處理。讓我們來看一個實際的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function Counter() {
const [number, setNumber] = useState(0);

return (
<>
<h1>{number}</h1>
<button onClick={() => {
setNumber(number + 1);
setNumber(number + 1);
setNumber(number + 1);
}}>+3</button>
</>
)
}

你可能會預期點擊按鈕後,數字會增加 3。但實際執行後會發現,每次點擊數字只增加了 1!這是因為在同一次渲染中,number 的值始終保持不變。上面的程式碼等同於連續執行三次 setNumber(0 + 1)

這就像是餐廳點餐一樣,服務生不會每點一道菜就跑一趟廚房,而是會等整桌客人都點完才送單。React 採用這種批次處理的機制,可以避免不必要的重複渲染,提升應用程式的效能。

使用更新函式解決問題

那麼,如果我們真的需要在同一個事件中連續更新狀態,該怎麼做呢?這時候就可以使用更新函式(updater function)的形式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function Counter() {
const [number, setNumber] = useState(0);

return (
<>
<h1>{number}</h1>
<button onClick={() => {
setNumber(n => n + 1);
setNumber(n => n + 1);
setNumber(n => n + 1);
}}>+3</button>
</>
)
}

使用更新函式時,React 會確保每次更新都是基於最新的狀態值。這樣一來,即使在同一個事件中多次更新,每次更新都能得到正確的結果。

不同情境的更新處理

在 React 中,狀態更新的處理方式會依據不同的情境而有所不同:

  1. 同一事件中的多次更新
    • React 會將這些更新打包在一起
    • 只進行一次重新渲染
    • 需要使用更新函式來確保正確的更新順序
  2. 不同事件的更新
    • 每次事件都會獨立處理
    • 每次點擊都會觸發一次重新渲染
    • 不需要特別使用更新函式

總結

了解 React 的批次更新機制對於開發更有效能的應用程式來說非常重要。當我們在同一個事件中需要多次更新狀態時,使用更新函式可以確保每次更新都是基於最新的狀態。這不只能讓我們的程式碼更可預測,也能避免一些常見的陷阱。

分享這些經驗,希望能幫助大家在處理狀態更新時更得心應手。如果你也遇到類似的情況,不妨試試看使用更新函式的方式!