diff --git a/src/content/learn/queueing-a-series-of-state-updates.md b/src/content/learn/queueing-a-series-of-state-updates.md index a63b7205b..b81863e21 100644 --- a/src/content/learn/queueing-a-series-of-state-updates.md +++ b/src/content/learn/queueing-a-series-of-state-updates.md @@ -1,23 +1,23 @@ --- -title: Queueing a Series of State Updates +title: 將一系列的 State 更新加入隊列 --- -Setting a state variable will queue another render. But sometimes you might want to perform multiple operations on the value before queueing the next render. To do this, it helps to understand how React batches state updates. +設置 state 變數將使另一個 render 加入隊列。但有時後你可能希望在加入隊列之前對該變數進行多個操作。為此,了解 React 如何批次更新 state 會有所幫助。 -* What "batching" is and how React uses it to process multiple state updates -* How to apply several updates to the same state variable in a row +* 什麼是「批次處理」以及 React 如何使用它來處理多個 state 更新 +* 如何連續對同一個 state 變數進行多次更新 -## React batches state updates {/*react-batches-state-updates*/} +## React 批次更新 state {/*react-batches-state-updates*/} -You might expect that clicking the "+3" button will increment the counter three times because it calls `setNumber(number + 1)` three times: +你可能預期點擊「+3」按鈕將增加計數三次,因為它調用了 `setNumber(number + 1)` 三次: @@ -47,7 +47,7 @@ h1 { display: inline-block; margin: 10px; width: 30px; text-align: center; } -However, as you might recall from the previous section, [each render's state values are fixed](/learn/state-as-a-snapshot#rendering-takes-a-snapshot-in-time), so the value of `number` inside the first render's event handler is always `0`, no matter how many times you call `setNumber(1)`: +但是,正如你可能還記得上一節中所提到, [每個 render 的 state 值都是固定的](/learn/state-as-a-snapshot#rendering-takes-a-snapshot-in-time),因此在第一個 render 事件處理程序的 `number` 值始終皆為`0`,無論呼叫多少次`setNumber(1)`: ```js setNumber(0 + 1); @@ -55,21 +55,21 @@ setNumber(0 + 1); setNumber(0 + 1); ``` -But there is one other factor at play here. **React waits until *all* code in the event handlers has run before processing your state updates.** This is why the re-render only happens *after* all these `setNumber()` calls. +但這裡還有另一個原因。**React 會等到*所有*在事件處理程序中的程式碼都運行完畢後才更新 state。** 這就是為什麼重新 render 只有在呼叫所有`setNumber()`*之後*發生。 -This might remind you of a waiter taking an order at the restaurant. A waiter doesn't run to the kitchen at the mention of your first dish! Instead, they let you finish your order, let you make changes to it, and even take orders from other people at the table. +這可能會讓你想起餐廳的服務生點菜。服務生不會在你點第一道菜時就跑到廚房!相反,他們會讓你一次點完餐,可以讓你進行更改,甚至接受餐桌上其他人的點餐。 -This lets you update multiple state variables--even from multiple components--without triggering too many [re-renders.](/learn/render-and-commit#re-renders-when-state-updates) But this also means that the UI won't be updated until _after_ your event handler, and any code in it, completes. This behavior, also known as **batching,** makes your React app run much faster. It also avoids dealing with confusing "half-finished" renders where only some of the variables have been updated. +這使你可以更新多個 state 變數——甚至可以從多個 component 進行更新——而不會觸發太多[重新 render。](/learn/render-and-commit#re-renders-when-state-updates) 這也意味著在事件處理程序及其中的任何程式碼執行完成*之前*, UI 不會進行更新。這種行為也稱為*批次處理*,使你的 React 應用程式執行得更快。它還避免了處理令人困惑的「半完成」render,也就是只更新了一些變數。 -**React does not batch across *multiple* intentional events like clicks**--each click is handled separately. Rest assured that React only does batching when it's generally safe to do. This ensures that, for example, if the first button click disables a form, the second click would not submit it again. +**React 不會批次處理*多個*主動事件(例如點擊)**——每次點擊都是單獨處理的。請放心,React 通常只在安全的情況下才進行批次處理。例如,如果第一次點擊按鈕禁用了表單,則第二次點擊將不會再次提交該表單。 -## Updating the same state multiple times before the next render {/*updating-the-same-state-multiple-times-before-the-next-render*/} +## 在下一次 Render 之前多次更新相同的 state {/*updating-the-same-state-multiple-times-before-the-next-render*/} -It is an uncommon use case, but if you would like to update the same state variable multiple times before the next render, instead of passing the *next state value* like `setNumber(number + 1)`, you can pass a *function* that calculates the next state based on the previous one in the queue, like `setNumber(n => n + 1)`. It is a way to tell React to "do something with the state value" instead of just replacing it. +這是一個不常見的範例,但如果你想在下一次 render 之前多次更新相同的 state 變數,像是`setNumber(n => n + 1)`,可以傳遞一個*函數*,該函數根據前一個在隊列中的 state 來計算下一個 state,而不是像`setNumber(number + 1)`傳遞*下一個 state 的值*。這是一種告訴 React「用 state 值做某事」而不只是替換它的方法。 -Try incrementing the counter now: +現在嘗試增加計數: @@ -99,10 +99,10 @@ h1 { display: inline-block; margin: 10px; width: 30px; text-align: center; } -Here, `n => n + 1` is called an **updater function.** When you pass it to a state setter: +這裡的 `n => n + 1` 稱為**更新函數**。當你將其傳遞給 state 設置器時: -1. React queues this function to be processed after all the other code in the event handler has run. -2. During the next render, React goes through the queue and gives you the final updated state. +1. React 將此函數加入隊列,以便在事件處理器程序的所有其他代碼運行後進行處理。 +2. 在下一次 Render 期間,React 會遍歷隊列並為你提供最終的更新 state。 ```js setNumber(n => n + 1); @@ -110,26 +110,26 @@ setNumber(n => n + 1); setNumber(n => n + 1); ``` -Here's how React works through these lines of code while executing the event handler: +以下是 React 在執行事件處理程序時如何處理這些程式碼: -1. `setNumber(n => n + 1)`: `n => n + 1` is a function. React adds it to a queue. -1. `setNumber(n => n + 1)`: `n => n + 1` is a function. React adds it to a queue. -1. `setNumber(n => n + 1)`: `n => n + 1` is a function. React adds it to a queue. +1. `setNumber(n => n + 1)`: `n => n + 1` 是一個函數。React 將其添加到隊列中。 +1. `setNumber(n => n + 1)`: `n => n + 1` 是一個函數。React 將其添加到隊列中。 +1. `setNumber(n => n + 1)`: `n => n + 1` 是一個函數。React 將其添加到隊列中。 -When you call `useState` during the next render, React goes through the queue. The previous `number` state was `0`, so that's what React passes to the first updater function as the `n` argument. Then React takes the return value of your previous updater function and passes it to the next updater as `n`, and so on: +當你在下一次 render 期間呼叫 `useState` ,React 會遍歷隊列。前一個 `number` 的 state 是 `0`,所以這就是 React 傳遞給第一個更新函數作為 `n` 參數的內容。然後 React 會獲取前一個更新函數的回傳值並將其作為參數 `n` 傳遞給下一個更新函式,以此類推: -| queued update | `n` | returns | +| 更新隊列 | `n` | 回傳 | |--------------|---------|-----| | `n => n + 1` | `0` | `0 + 1 = 1` | | `n => n + 1` | `1` | `1 + 1 = 2` | | `n => n + 1` | `2` | `2 + 1 = 3` | -React stores `3` as the final result and returns it from `useState`. +React 從 `useState` 存儲 `3` 最為最終的結果。 -This is why clicking "+3" in the above example correctly increments the value by 3. -### What happens if you update state after replacing it {/*what-happens-if-you-update-state-after-replacing-it*/} +這就是為什麼在前面的案例中點擊「+3」會正確地將值增加 3。 +### 如果在替換後更新 state 會發生什麼 {/*what-happens-if-you-update-state-after-replacing-it*/} -What about this event handler? What do you think `number` will be in the next render? +這個事件處理程序如何?你認為下一個 render 時 `number` 會是什麼? ```js