From aa9a5cff09291736d57414087fb89346fe87a28b Mon Sep 17 00:00:00 2001 From: Vitalii Perehonchuk Date: Wed, 24 Jul 2024 14:31:40 +0300 Subject: [PATCH] Apply suggestions from code review Co-authored-by: Alina Listunova --- src/content/learn/state-as-a-snapshot.md | 38 ++++++++++++------------ 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/content/learn/state-as-a-snapshot.md b/src/content/learn/state-as-a-snapshot.md index 56e39230f..eb3ec8395 100644 --- a/src/content/learn/state-as-a-snapshot.md +++ b/src/content/learn/state-as-a-snapshot.md @@ -19,7 +19,7 @@ title: Стан як зняток ## Задання стану запускає рендери {/*setting-state-triggers-renders*/} -Можна уявляти, що користувацький інтерфейс змінюється безпосередньо внаслідок дії користувача, наприклад, клацання. В React же це працює трохи інакше, ніж передбачає ця ментальна модель. На попередній сторінці ви побачили, що [задання стану просить React про повторний рендер](/learn/render-and-commit#step-1-trigger-a-render). Це означає, що щоб інтерфейс зреагував на подію, необхідно *оновити стан*. +Можна уявляти, що інтерфейс користувача змінюється безпосередньо внаслідок дії користувача, наприклад, клацання. У React це працює трохи інакше, ніж передбачає ця ментальна модель. На попередній сторінці ви побачили, що [задання стану просить React про повторний рендер](/learn/render-and-commit#step-1-trigger-a-render). Це означає, що необхідно *оновити стан*, щоб інтерфейс зреагував на подію. У цьому прикладі, якщо натиснути "надіслати", то `setIsSent(true)` каже React виконати повторний рендер UI: @@ -64,8 +64,8 @@ label, textarea { margin-bottom: 10px; display: block; } Ось що відбувається, коли ви клацаєте кнопку: 1. Виконується обробник події `onSubmit`. -2. `setIsSent(true)` задає `isSent` значення `true`, і таким чином додає в чергу новий рендер. -3. React виконує повторний рендер компонента, згідно з новим значенням `isSent`. +2. `setIsSent(true)` задає `isSent` значення `true` і так додає до черги новий рендер. +3. React виконує повторний рендер компонента згідно з новим значенням `isSent`. Погляньмо уважніше на взаємозв'язок між станом і рендерингом. @@ -129,7 +129,7 @@ h1 { display: inline-block; margin: 10px; width: 30px; text-align: center; } Зверніть увагу, що `number` збільшується лише раз за одне клацання! -**Задання стану змінює його лише для *наступного* рендеру.** Під час першого рендеру `number` був `0`. Саме тому в обробнику `onClick` того конкретного рендеру значення `number` все одно `0`, навіть після виклику `setNumber(number + 1)`: +**Задання стану змінює його лише для *наступного* рендеру.** Під час першого рендеру `number` був `0`. Саме тому в обробнику `onClick` того конкретного рендеру значення `number` все одно `0` навіть після виклику `setNumber(number + 1)`: ```js ``` -Ось що обробник клацання цієї кнопки каже React робити: +Ось що обробник клацання цієї кнопки запитує в React: 1. `setNumber(number + 1)`: `number` — `0`, тож `setNumber(0 + 1)`. - * React готується змінити `number` на `1` в наступному рендері. + * React готується змінити `number` на `1` у наступному рендері. 2. `setNumber(number + 1)`: `number` — `0`, тож `setNumber(0 + 1)`. - * React готується змінити `number` на `1` в наступному рендері. + * React готується змінити `number` на `1` у наступному рендері. 3. `setNumber(number + 1)`: `number` — `0`, тож `setNumber(0 + 1)`. - * React готується змінити `number` на `1` в наступному рендері. + * React готується змінити `number` на `1` у наступному рендері. -Навіть попри те, що ви викликали `setNumber(number + 1)` тричі, в обробнику подій *поточного рендеру* `number` завжди дорівнює `0`, тож ви задаєте стан `1` тричі. Саме тому, коли завершується виконання вашого обробника помилок, React виконує повторний рендер компонента, де `number` дорівнює `1`, а не `3`. +Навіть попри те, що ви викликали `setNumber(number + 1)` тричі, в обробнику подій *поточного рендеру* `number` завжди дорівнює `0`, тож ви задаєте стану значення `1` тричі. Саме тому, коли завершується виконання вашого обробника помилок, React виконує повторний рендер компонента, де `number` дорівнює `1`, а не `3`. Також це можна візуалізувати, уявно замінюючи змінні стану їхніми значеннями в вашому коді. Оскільки змінна стану `number` дорівнює `0` для *поточного рендеру*, обробник подій має наступний вигляд: @@ -170,7 +170,7 @@ h1 { display: inline-block; margin: 10px; width: 30px; text-align: center; } }}>+3 ``` -Саме тому клацання кнопки знову задасть лічильнику значення `2`, потім `3` — після наступного клацання, і так далі. +Саме тому клацання кнопки знову задасть лічильнику значення `2`, після наступного клацання — `3` і так далі. ## Стан протягом часу {/*state-over-time*/} @@ -210,7 +210,7 @@ setNumber(0 + 5); alert(0); ``` -Але що якщо поставити таймер на виведення повідомлення, щоб воно спрацювало лише *після* повторного рендеру компонента? Буде "0" чи "5"? Вгадайте! +А якщо поставити таймер на виведення повідомлення, щоб воно спрацювало лише *після* повторного рендеру компонента? Буде "0" чи "5"? Вгадайте! @@ -254,7 +254,7 @@ setTimeout(() => { **Значення змінної стану ніколи не змінюється протягом одного рендеру,** навіть якщо код обробника події є асинхронним. Всередині `onClick` *поточного рендеру* значення `number` усе одно залишається `0`, навіть після виклику `setNumber(number + 5)`. Її значення "зафіксувалося", коли React "зробив зняток" UI, викликавши ваш компонент. -Ось приклад того, що робить обробники помилок більш захищеними щодо помилок хронометражу. Нижче — форма, що надсилає повідомлення з п'ятисекундною затримкою. Уявіть такий сценарій: +Ось приклад, як це захищає обробники подій від помилок хронометражу. Нижче — форма, що надсилає повідомлення з п'ятисекундною затримкою. Уявіть такий сценарій: 1. Ви натискаєте кнопку "Надіслати", надсилаючи "Привіт" Анні. 2. Перш ніж закінчиться п'ятисекундна затримка, ви змінюєте значення в полі "Кому" на "Богдан". @@ -305,7 +305,7 @@ label, textarea { margin-bottom: 10px; display: block; } -**React підтримує значення стану "зафіксованими" в межах обробників подій одного рендеру.** Немає потреби перейматися тим, чи стан змінився, поки виконувався код. +**React тримає значення стану "зафіксованими" в межах обробників подій одного рендеру.** Немає потреби перейматися тим, чи стан змінився, поки виконувався код. Але що якщо хочеться зчитати найсвіжіший стан перед повторним рендером? Знадобиться скористатися [функцією-оновлювачем стану](/learn/queueing-a-series-of-state-updates), про яку мова піде на наступній сторінці! @@ -316,7 +316,7 @@ label, textarea { margin-bottom: 10px; display: block; } * Коли викликається `useState`, React видає зняток стану *для конкретного поточного рендеру*. * Змінні та обробники подій не "переживають" повторні рендери. Кожний рендер має власні обробники подій. * Кожний рендер (а також функції в ньому) завжди "бачить" зняток стану, який React видав *цьому конкретному* рендеру. -* Можна уявно підставити стан у обробниках подій, подібного до того, як ми уявляємо JSX після рендеру. +* Можна уявно підставити стан в обробниках подій — подібного до того, як ми уявляємо JSX після рендеру. * Обробники подій, створені в минулому, мають значення стану з тих рендерів, у яких вони створені. @@ -362,9 +362,9 @@ h1 { margin-top: 20px; } -Додайте до обробника клацання `alert`. Коли світлофор світиться зеленим і каже "Йдіть", натискання кнопки повинно видавати "Далі буде Стійте". Коли світлофор світиться червоним і каже "Стійте", натискання кнопки повинно видавати "Далі буде Йдіть". +Додайте `alert` до обробника клацання. Коли світлофор світиться зеленим і каже "Йдіть", натискання кнопки повинно видавати "Далі буде Стійте". Коли світлофор світиться червоним і каже "Стійте", натискання кнопки повинно видавати "Далі буде Йдіть". -Чи важливо те, чи поставити `alert` до виклику `setWalk`, чи після? +Чи важливий порядок: розташувати `alert` до виклику `setWalk` або навпаки? @@ -404,7 +404,7 @@ h1 { margin-top: 20px; } -Незалежно від того, чи ви поставите виклик `alert` до виклику `setWalk`, чи після, це дасть один і той же результат. Значення `walk` у рендері — зафіксовано. Виклик `setWalk` змінить його лише для *наступного* рендеру, але не вплине на обробник подій з попереднього. +Чи ви поставите виклик `alert` до виклику `setWalk`, чи після — буде той самий результат. Значення `walk` у рендері зафіксоване. Виклик `setWalk` змінить його лише для *наступного* рендеру, але не вплине на обробник подій з попереднього. Цей рядок може спершу здаватися контрінтуїтивним: @@ -412,9 +412,9 @@ h1 { margin-top: 20px; } alert(walk ? 'Далі буде Стійте' : 'Далі буде Йдіть'); ``` -Але він має зміст, якщо прочитати його так: "Якщо світлофор показує 'Йдіть', то повідомлення повинно звучати 'Далі буде Стійте.'". Змінна `walk` усередині вашого обробника подій відповідає значенню `walk` конкретного рендеру й не змінюється. +Але він досить логічний, якщо прочитати його так: "Якщо світлофор показує 'Йдіть', то повідомлення повинно звучати 'Далі буде Стійте.'". Змінна `walk` усередині вашого обробника подій відповідає значенню `walk` конкретного рендеру й не змінюється. -Перевірити, що це саме так, можна застосувавши підхід підстановки. Коли `walk` дорівнює `true`, вийде: +Можна перевірити, що це саме так, застосувавши метод заміни. Коли `walk` дорівнює `true`, отримаємо: ```js