You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/content/learn/state-as-a-snapshot.md
+68-68
Original file line number
Diff line number
Diff line change
@@ -1,27 +1,27 @@
1
1
---
2
-
title: State as a Snapshot
2
+
title: 如同快照的 State
3
3
---
4
4
5
5
<Intro>
6
6
7
-
State variables might look like regular JavaScript variables that you can read and write to. However, state behaves more like a snapshot. Setting it does not change the state variable you already have, but instead triggers a re-render.
7
+
State 變數或許和可讀寫的普通 JavaScript 變數看起來很像。然而,state 的行為更像是一張快照(snapshot)。設定 state 並不會改變你已有的 state 變數,而是會觸發重新 render。
8
8
9
9
</Intro>
10
10
11
11
<YouWillLearn>
12
12
13
-
*How setting state triggers re-renders
14
-
*When and how state updates
15
-
*Why state does not update immediately after you set it
16
-
*How event handlers access a "snapshot" of the state
13
+
*設定 state 是如何觸發重新 render
14
+
* state 更新的時機和方式
15
+
* state 在設定後並未立即更新的原因
16
+
* event handler 是如何取得 state 的「快照」
17
17
18
18
</YouWillLearn>
19
19
20
-
## Setting state triggers renders {/*setting-state-triggers-renders*/}
20
+
## 設定 state 會觸發 render {/*setting-state-triggers-renders*/}
21
21
22
-
You might think of your user interface as changing directly in response to the user event like a click. In React, it works a little differently from this mental model. On the previous page, you saw that [setting state requests a re-render](/learn/render-and-commit#step-1-trigger-a-render) from React. This means that for an interface to react to the event, you need to *update the state*.
22
+
你可能會認為使用者介面會直接對點擊等使用者事件做出改變以作為回應。在 React 裡,它的運作方式和這種思維模型有點不同。在前一章,你看過來自 React 的[設定 state 來請求重新 render](/learn/render-and-commit#step-1-trigger-a-render)。這意味著介面若要為特定的事件做出回應,則需要*更新 state*。
23
23
24
-
In this example, when you press "send", `setIsSent(true)`tells React to re-render the UI:
["Rendering"](/learn/render-and-commit#step-2-react-renders-your-components) means that React is calling your component, which is a function. The JSX you return from that function is like a snapshot of the UI in time. Its props, event handlers, and local variables were all calculated **using its state at the time of the render.**
Unlike a photograph or a movie frame, the UI "snapshot" you return is interactive. It includes logic like event handlers that specify what happens in response to inputs. React updates the screen to match this snapshot and connects the event handlers. As a result, pressing a button will trigger the click handler from your JSX.
3. React then updates the screen to match the snapshot you've returned.
80
+
1. React 再次呼叫函式。
81
+
2.函式回傳一張全新的 JSX 快照。
82
+
3.接著,React 更新畫面,使畫面與你回傳的快照相符。
83
83
84
84
<IllustrationBlocksequential>
85
85
<Illustration caption="React executing the function" src="/images/docs/illustrations/i_render1.png" />
86
86
<Illustration caption="Calculating the snapshot" src="/images/docs/illustrations/i_render2.png" />
87
87
<Illustration caption="Updating the DOM tree" src="/images/docs/illustrations/i_render3.png" />
88
88
</IllustrationBlock>
89
89
90
-
As a component's memory, state is not like a regular variable that disappears after your function returns. State actually "lives" in React itself--as if on a shelf!--outside of your function. When React calls your component, it gives you a snapshot of the state for that particular render. Your component returns a snapshot of the UI with a fresh set of props and event handlers in its JSX, all calculated **using the state values from that render!**
90
+
State 是 component 的記憶,它和那種函式回傳後就消失的一般變數不同。State 其實「存在於」React 本身 - 如同放在架子上!- 在函式之外。當 React 呼叫 component,它會是你特定 render 的 state 快照。Component 回傳的 UI 快照內的 JSX 裡有最新的 props 和 event handler,全都是**使用那一次 render 的 state 值**所計算出來的。
91
91
92
92
<IllustrationBlocksequential>
93
93
<Illustrationcaption="You tell React to update the state"src="/images/docs/illustrations/i_state-snapshot1.png" />
94
94
<Illustrationcaption="React updates the state value"src="/images/docs/illustrations/i_state-snapshot2.png" />
95
95
<Illustrationcaption="React passes a snapshot of the state value into the component"src="/images/docs/illustrations/i_state-snapshot3.png" />
96
96
</IllustrationBlock>
97
97
98
-
Here's a little experiment to show you how this works. In this example, you might expect that clicking the "+3" button would increment the counter three times because it calls `setNumber(number + 1)` three times.
Notice that `number`only increments once per click!
130
+
注意,`number`在每次點擊只會遞增一次!
131
131
132
-
**Setting state only changes it for the *next* render.**During the first render, `number`was`0`. This is why, in *that render's*`onClick` handler, the value of `number` is still `0` even after `setNumber(number + 1)` was called:
Even though you called `setNumber(number + 1)`three times, in *this render's* event handler `number`is always `0`, so you set the state to`1`three times. This is why, after your event handler finishes, React re-renders the component with `number` equal to `1` rather than `3`.
You can also visualize this by mentally substituting state variables with their values in your code. Since the `number`state variable is `0` for *this render*, its event handler looks like this:
Surprised? If you use the substitution method, you can see the "snapshot" of the state passed to the alert.
244
+
驚不驚訝?如果你使用替換法,你就可以看到傳入提示框的 state「快照」。
245
245
246
246
```js
247
247
setNumber(0+5);
@@ -250,16 +250,16 @@ setTimeout(() => {
250
250
}, 3000);
251
251
```
252
252
253
-
The state stored in React may have changed by the time the alert runs, but it was scheduled using a snapshot of the state at the time the user interacted with it!
253
+
儲存在 React 裡的 state 在提示框執行時可能已改變,但它是用使用者與其互動當下的 state 快照來安排的!
254
254
255
-
**A state variable's value never changes within a render,** even if its event handler's code is asynchronous. Inside *that render's*`onClick`, the value of `number` continues to be `0` even after `setNumber(number + 5)` was called. Its value was "fixed" when React "took the snapshot" of the UI by calling your component.
Here is an example of how that makes your event handlers less prone to timing mistakes. Below is a form that sends a message with a five-second delay. Imagine this scenario:
1.You press the "Send" button, sending "Hello" to Alice.
260
-
2.Before the five-second delay ends, you change the value of the "To" field to "Bob".
259
+
1.你按下「傳送」按鈕,向 Alice 傳送「Hi」。
260
+
2.在五秒的延遲結束之前,你將「To」欄位的值更改為「Bob」。
261
261
262
-
What do you expect the `alert`to display? Would it display, "You said Hello to Alice"? Or would it display, "You said Hello to Bob"? Make a guess based on what you know, and then try it:
262
+
你預期 `alert`顯示什麼?它會顯示「You said Hello to Alice」還是「You said Hello to Bob」?根據所學猜一猜並試試看:
**React keeps the state values "fixed" within one render's event handlers.**You don't need to worry whether the state has changed while the code is running.
308
+
**React 會使 state 值在同一次 render 內的 event handler 保持「固定不變」。**你不需要擔心 state 在程式碼執行時有所異動。
309
309
310
-
But what if you wanted to read the latest state before a re-render? You'll want to use a [state updater function](/learn/queueing-a-series-of-state-updates), covered on the next page!
310
+
但要是你希望在重新 render 之前讀取最新的 state 呢?你將會需要使用 [state 的更新函式](/learn/queueing-a-series-of-state-updates),這會下一章節中介紹!
311
311
312
312
<Recap>
313
313
314
-
*Setting state requests a new render.
315
-
* React stores state outside of your component, as if on a shelf.
316
-
*When you call `useState`, React gives you a snapshot of the state *for that render*.
317
-
*Variables and event handlers don't "survive" re-renders. Every render has its own event handlers.
318
-
*Every render (and functions inside it) will always "see" the snapshot of the state that React gave to *that* render.
319
-
*You can mentally substitute state in event handlers, similarly to how you think about the rendered JSX.
320
-
*Event handlers created in the past have the state values from the render in which they were created.
314
+
*設定 state 會請求一次新的 render。
315
+
* React 將 state 儲存在 component 外,好比在架子上一樣。
316
+
*當你呼叫 `useState`,React 會*為該次 render* 拍一張 state 的快照。
*過去建立的 event handler 保有它們被建立的那一次 render 中的 state 值。
321
321
322
322
</Recap>
323
323
324
324
325
325
326
326
<Challenges>
327
327
328
-
#### Implement a traffic light {/*implement-a-traffic-light*/}
328
+
#### 實作紅綠燈 {/*implement-a-traffic-light*/}
329
329
330
-
Here is a crosswalk light component that toggles when the button is pressed:
330
+
以下是一個紅綠燈 component,按按鈕可以切換它的狀態:
331
331
332
332
<Sandpack>
333
333
@@ -362,13 +362,13 @@ h1 { margin-top: 20px; }
362
362
363
363
</Sandpack>
364
364
365
-
Add an `alert` to the click handler. When the light is green and says "Walk", clicking the button should say "Stop is next". When the light is red and says "Stop", clicking the button should say "Walk is next".
365
+
請在 click handler 裡加入一個 `alert`。當燈是綠色的並顯示「Walk」時,點擊按鈕應顯示「Stop is next」。當燈是紅色的並顯示「Stop」時,點擊按鈕應顯示「Walk is next」。
366
366
367
-
Does it make a difference whether you put the `alert`before or after the `setWalk`call?
367
+
無論你將 `alert`放在呼叫 `setWalk`之前還是之後,是否會有不同呢?
368
368
369
369
<Solution>
370
370
371
-
Your `alert`should look like this:
371
+
`alert`看起來應該像這樣:
372
372
373
373
<Sandpack>
374
374
@@ -404,17 +404,17 @@ h1 { margin-top: 20px; }
404
404
405
405
</Sandpack>
406
406
407
-
Whether you put it before or after the `setWalk`call makes no difference. That render's value of `walk`is fixed. Calling `setWalk`will only change it for the *next* render, but will not affect the event handler from the previous render.
But it makes sense if you read it as: "If the traffic light shows 'Walk now', the message should say 'Stop is next.'" The `walk` variable inside your event handler matches that render's value of `walk`and does not change.
0 commit comments