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
+19-19Lines changed: 19 additions & 19 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -19,7 +19,7 @@ title: Стан як зняток
19
19
20
20
## Задання стану запускає рендери {/*setting-state-triggers-renders*/}
21
21
22
-
Можна уявляти, що користувацький інтерфейс змінюється безпосередньо внаслідок дії користувача, наприклад, клацання. В React же це працює трохи інакше, ніж передбачає ця ментальна модель. На попередній сторінці ви побачили, що [задання стану просить React про повторний рендер](/learn/render-and-commit#step-1-trigger-a-render). Це означає, що щоб інтерфейс зреагував на подію, необхідно *оновити стан*.
22
+
Можна уявляти, що інтерфейс користувача змінюється безпосередньо внаслідок дії користувача, наприклад, клацання. У React це працює трохи інакше, ніж передбачає ця ментальна модель. На попередній сторінці ви побачили, що [задання стану просить React про повторний рендер](/learn/render-and-commit#step-1-trigger-a-render). Це означає, що необхідно *оновити стан*, щоб інтерфейс зреагував на подію.
23
23
24
24
У цьому прикладі, якщо натиснути "надіслати", то `setIsSent(true)` каже React виконати повторний рендер UI:
Зверніть увагу, що `number` збільшується лише раз за одне клацання!
131
131
132
-
**Задання стану змінює його лише для *наступного* рендеру.** Під час першого рендеру `number` був `0`. Саме тому в обробнику `onClick` того конкретного рендеру значення `number` все одно `0`, навіть після виклику `setNumber(number + 1)`:
132
+
**Задання стану змінює його лише для *наступного* рендеру.** Під час першого рендеру `number` був `0`. Саме тому в обробнику `onClick` того конкретного рендеру значення `number` все одно `0` навіть після виклику `setNumber(number + 1)`:
Ось що обробник клацання цієї кнопки каже React робити:
142
+
Ось що обробник клацання цієї кнопки запитує в React:
143
143
144
144
1.`setNumber(number + 1)`: `number` — `0`, тож `setNumber(0 + 1)`.
145
-
* React готується змінити `number` на `1`в наступному рендері.
145
+
* React готується змінити `number` на `1`у наступному рендері.
146
146
2.`setNumber(number + 1)`: `number` — `0`, тож `setNumber(0 + 1)`.
147
-
* React готується змінити `number` на `1`в наступному рендері.
147
+
* React готується змінити `number` на `1`у наступному рендері.
148
148
3.`setNumber(number + 1)`: `number` — `0`, тож `setNumber(0 + 1)`.
149
-
* React готується змінити `number` на `1`в наступному рендері.
149
+
* React готується змінити `number` на `1`у наступному рендері.
150
150
151
-
Навіть попри те, що ви викликали `setNumber(number + 1)` тричі, в обробнику подій *поточного рендеру*`number` завжди дорівнює `0`, тож ви задаєте стан`1` тричі. Саме тому, коли завершується виконання вашого обробника помилок, React виконує повторний рендер компонента, де `number` дорівнює `1`, а не `3`.
151
+
Навіть попри те, що ви викликали `setNumber(number + 1)` тричі, в обробнику подій *поточного рендеру*`number` завжди дорівнює `0`, тож ви задаєте стану значення`1` тричі. Саме тому, коли завершується виконання вашого обробника помилок, React виконує повторний рендер компонента, де `number` дорівнює `1`, а не `3`.
152
152
153
153
Також це можна візуалізувати, уявно замінюючи змінні стану їхніми значеннями в вашому коді. Оскільки змінна стану `number` дорівнює `0` для *поточного рендеру*, обробник подій має наступний вигляд:
Саме тому клацання кнопки знову задасть лічильнику значення `2`, потім `3` — після наступного клацання, і так далі.
173
+
Саме тому клацання кнопки знову задасть лічильнику значення `2`, після наступного клацання — `3` і так далі.
174
174
175
175
## Стан протягом часу {/*state-over-time*/}
176
176
@@ -210,7 +210,7 @@ setNumber(0 + 5);
210
210
alert(0);
211
211
```
212
212
213
-
Але що якщо поставити таймер на виведення повідомлення, щоб воно спрацювало лише *після* повторного рендеру компонента? Буде "0" чи "5"? Вгадайте!
213
+
А якщо поставити таймер на виведення повідомлення, щоб воно спрацювало лише *після* повторного рендеру компонента? Буде "0" чи "5"? Вгадайте!
214
214
215
215
<Sandpack>
216
216
@@ -254,7 +254,7 @@ setTimeout(() => {
254
254
255
255
**Значення змінної стану ніколи не змінюється протягом одного рендеру,** навіть якщо код обробника події є асинхронним. Всередині `onClick`*поточного рендеру* значення `number` усе одно залишається `0`, навіть після виклику `setNumber(number + 5)`. Її значення "зафіксувалося", коли React "зробив зняток" UI, викликавши ваш компонент.
256
256
257
-
Ось приклад того, що робить обробники помилок більш захищеними щодо помилок хронометражу. Нижче — форма, що надсилає повідомлення з п'ятисекундною затримкою. Уявіть такий сценарій:
257
+
Ось приклад, як це захищає обробники подій від помилок хронометражу. Нижче — форма, що надсилає повідомлення з п'ятисекундною затримкою. Уявіть такий сценарій:
258
258
259
259
1. Ви натискаєте кнопку "Надіслати", надсилаючи "Привіт" Анні.
260
260
2. Перш ніж закінчиться п'ятисекундна затримка, ви змінюєте значення в полі "Кому" на "Богдан".
**React підтримує значення стану "зафіксованими" в межах обробників подій одного рендеру.** Немає потреби перейматися тим, чи стан змінився, поки виконувався код.
308
+
**React тримає значення стану "зафіксованими" в межах обробників подій одного рендеру.** Немає потреби перейматися тим, чи стан змінився, поки виконувався код.
309
309
310
310
Але що якщо хочеться зчитати найсвіжіший стан перед повторним рендером? Знадобиться скористатися [функцією-оновлювачем стану](/learn/queueing-a-series-of-state-updates), про яку мова піде на наступній сторінці!
* Коли викликається `useState`, React видає зняток стану *для конкретного поточного рендеру*.
317
317
* Змінні та обробники подій не "переживають" повторні рендери. Кожний рендер має власні обробники подій.
318
318
* Кожний рендер (а також функції в ньому) завжди "бачить" зняток стану, який React видав *цьому конкретному* рендеру.
319
-
* Можна уявно підставити стан у обробниках подій, подібного до того, як ми уявляємо JSX після рендеру.
319
+
* Можна уявно підставити стан в обробниках подій — подібного до того, як ми уявляємо JSX після рендеру.
320
320
* Обробники подій, створені в минулому, мають значення стану з тих рендерів, у яких вони створені.
321
321
322
322
</Recap>
@@ -362,9 +362,9 @@ h1 { margin-top: 20px; }
362
362
363
363
</Sandpack>
364
364
365
-
Додайте до обробника клацання`alert`. Коли світлофор світиться зеленим і каже "Йдіть", натискання кнопки повинно видавати "Далі буде Стійте". Коли світлофор світиться червоним і каже "Стійте", натискання кнопки повинно видавати "Далі буде Йдіть".
365
+
Додайте `alert`до обробника клацання. Коли світлофор світиться зеленим і каже "Йдіть", натискання кнопки повинно видавати "Далі буде Стійте". Коли світлофор світиться червоним і каже "Стійте", натискання кнопки повинно видавати "Далі буде Йдіть".
366
366
367
-
Чи важливо те, чи поставити `alert` до виклику `setWalk`, чи після?
367
+
Чи важливий порядок: розташувати `alert` до виклику `setWalk` або навпаки?
368
368
369
369
<Solution>
370
370
@@ -404,17 +404,17 @@ h1 { margin-top: 20px; }
404
404
405
405
</Sandpack>
406
406
407
-
Незалежно від того, чи ви поставите виклик `alert` до виклику `setWalk`, чи після, це дасть один і той же результат. Значення `walk` у рендері — зафіксовано. Виклик `setWalk` змінить його лише для *наступного* рендеру, але не вплине на обробник подій з попереднього.
407
+
Чи ви поставите виклик `alert` до виклику `setWalk`, чи після — буде той самий результат. Значення `walk` у рендері зафіксоване. Виклик `setWalk` змінить його лише для *наступного* рендеру, але не вплине на обробник подій з попереднього.
408
408
409
409
Цей рядок може спершу здаватися контрінтуїтивним:
410
410
411
411
```js
412
412
alert(walk ?'Далі буде Стійте':'Далі буде Йдіть');
413
413
```
414
414
415
-
Але він має зміст, якщо прочитати його так: "Якщо світлофор показує 'Йдіть', то повідомлення повинно звучати 'Далі буде Стійте.'". Змінна `walk` усередині вашого обробника подій відповідає значенню `walk` конкретного рендеру й не змінюється.
415
+
Але він досить логічний, якщо прочитати його так: "Якщо світлофор показує 'Йдіть', то повідомлення повинно звучати 'Далі буде Стійте.'". Змінна `walk` усередині вашого обробника подій відповідає значенню `walk` конкретного рендеру й не змінюється.
416
416
417
-
Перевірити, що це саме так, можна застосувавши підхід підстановки. Коли `walk` дорівнює `true`, вийде:
417
+
Можна перевірити, що це саме так, застосувавши метод заміни. Коли `walk` дорівнює `true`, отримаємо:
0 commit comments