這裡有一個簡單的情境,有一個初始值為 20 的 age
變數,我們想要在按下按鈕時將 age
增加 1。
function App() {
const [age, setAge] = useState(20)
function handleClick() {
setAge(age + 1); // 21
setAge(age + 1); // 22
setAge(age + 1); // 23
}
}
我們可能期望在點擊三次後 age
更新為 23,但實際情況並非如此,這種意外行為的原因在於 React 的狀態更新行為。
當調用 set 函式時,React 不會立即在當前運行的程式碼中更新狀態。
它會批量處理這些更新並 稍後處理 它們,在我們的範例中,每個 setAge(age + 1)
調用都使用相同的初始值 age
(即 20),因此不論執行幾次 setAge
,最後的結果都會是 20 + 1 = 21。
function App() {
const [age, setAge] = useState(20)
function handleClick() {
setAge(age + 1); // setAge(20 + 1)
setAge(age + 1); // setAge(20 + 1)
setAge(age + 1); // setAge(20 + 1)
}
}
為確保狀態更新正確反映了前一個狀態,我們可以在調用 set 函式時使用 callback function:
function App() {
const [age, setAge] = useState(20)
function handleClick() {
setAge((a) => a + 1); // setAge(20 => 21)
setAge((a) => a + 1); // setAge(21 => 22)
setAge((a) => a + 1); // setAge(22 => 23)
}
}
在這個修改後的程式碼中,它接受待處理的狀態並基於它計算下一個狀態,這種方法確保每個狀態更新按順序執行,並且正確地反映了前一個狀態。
當需要多次更新 React 元件的狀態時,我們必須小心 React 處理狀態更新的行為,React 並不會立即處理多次連續的狀態更新,這可能導致意外的結果。
為了確保狀態更新按照我們的期望進行,我們可以使用 callback function 來處理狀態更新,這樣可以確保每次更新都基於前一個狀態執行,從而避免不必要的錯誤。