Skip to content

Commit

Permalink
Apply suggestions from code review
Browse files Browse the repository at this point in the history
Co-authored-by: Alina Listunova <[email protected]>
  • Loading branch information
undead404 and alinkedd authored Jul 24, 2024
1 parent bf516a5 commit c3a03b0
Showing 1 changed file with 18 additions and 18 deletions.
36 changes: 18 additions & 18 deletions src/content/learn/queueing-a-series-of-state-updates.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ title: Додавання до черги низки оновлень стану

<Intro>

Задання змінної стану ставить у чергу ще один рендер. Проте іноді може викинути потреба виконати кілько операцій над значенням, перш ніж додавати до черги новий рендер. Щоб це зробити, корисно розуміти, як React групує оновлення стану.
Задання значення змінній стану ставить у чергу ще один рендер. Проте іноді може виникнути потреба виконати кілька операцій над значенням, перш ніж додавати до черги новий рендер. Щоб це зробити, корисно розуміти, як React групує оновлення стану.

</Intro>

Expand Down Expand Up @@ -55,11 +55,11 @@ setNumber(0 + 1);
setNumber(0 + 1);
```

Але тут грає роль ще один чинник. **React чекає, поки не виконається *ввесь* код у обробниках подій, перш ніж обробляти ваші оновлення стану.** Саме тому повторний рендер відбувається *після* всіх цих викликів `setNumber()`.
Але тут грає роль ще один чинник. **React чекає, поки не виконається *весь* код у обробниках подій, перш ніж обробляти ваші оновлення стану.** Саме тому повторний рендер відбувається *після* всіх цих викликів `setNumber()`.

Це може нагадати офіціанта, що приймає замовлення в ресторані. Він не бігає на кухню, коли названа одна страва! Замість цього він дає змогу зробити замовлення повністю, внести до нього зміни й навіть прийняти замовлення від інших людей за тим же столом.

ʼ<Illustration src="/images/docs/illustrations/i_react-batching.png" alt="Елегантна курсорка в ресторані робить кілька замовлень в бік React, що грає роль офіціанта. Коли вона кілька разів викликає setState(), офіціант записує останнє з запитаного як остаточне замовлення." />
<Illustration src="/images/docs/illustrations/i_react-batching.png" alt="Елегантна курсорка в ресторані робить кілька замовлень у React, що грає роль офіціанта. Коли вона кілька разів викликає setState(), офіціант записує останнє з запитаного як остаточне замовлення." />

Це дає змогу оновлювати кілька змінних стану — навіть з різних компонентів — не запускаючи забагато [повторних рендерів.](/learn/render-and-commit#re-renders-when-state-updates) Але це також означає, що UI не оновиться, поки не завершиться вам обробник події та ввесь код у ньому. Така логіка, також відома як **групування,** робить ваш застосунок на React куди швидшим. Також це позбавляє потреби мати справу з безглуздими "напівготовими" рендерами, в яких оновилась лише частина змінних.

Expand Down Expand Up @@ -102,21 +102,21 @@ h1 { display: inline-block; margin: 10px; width: 30px; text-align: center; }
Тут `n => n + 1` зветься **функцією-оновлювачем.** Коли ви передаєте її до сетера стану:

1. React додає цю функцію в чергу до обробки, коли решта коду в обробнику події завершилася.
2. Під час наступного рендеру React йде по черзі та видає остаточний оновлений стан.
2. Під час наступного рендеру React йде чергою та видає остаточний оновлений стан.

```js
setNumber(n => n + 1);
setNumber(n => n + 1);
setNumber(n => n + 1);
```

Ось як React проходить по цих рядках коду, виконуючи обробник подій:
Ось як React проходить цими рядками коду, виконуючи обробник подій:

1. `setNumber(n => n + 1)`: `n => n + 1` — це функція. React додає її до черги.
2. `setNumber(n => n + 1)`: `n => n + 1` — це функція. React додає її до черги.
3. `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 додає її до черги.

Коли `useState` викликається під час наступного рендеру, React проходить по черзі. Попередній стан `number` був `0`, і це саме те, що React передає до першої функції-оновлювача як аргумент `n`. Потім React бере повернене значення нашої попередньої функції-оновлювача й передає його до наступного оновлювача як `n`, і так далі:
Коли `useState` викликається під час наступного рендеру, React проходить чергою. Попередній стан `number` був `0`, і це саме те, що React передає до першої функції-оновлювача як аргумент `n`. Потім React бере повернене значення нашої попередньої функції-оновлювача й передає його до наступного оновлювача як `n`, і так далі:

| оновлення в черзі | `n` | повертає |
| ----------------- | --- | ----------- |
Expand All @@ -129,7 +129,7 @@ React зберігає `3` як остаточний результат і по
Саме тому клацання "+3" у прикладі вище коректно збільшує значення на 3.
### Що відбудеться, якщо оновити стан, спершу замінивши його {/*what-happens-if-you-update-state-after-replacing-it*/}

Як щодо цього обробника подій? Як гадаєте, чим буде `number` у наступному рендері?
Як щодо цього обробника подій? Як гадаєте, яке значення матиме `number` у наступному рендері?

```js
<button onClick={() => {
Expand Down Expand Up @@ -185,7 +185,7 @@ React зберігає `6` як остаточний результат і по

</Note>

### Що станеться, якщо замінити стан, перед тим оновивши його {/*what-happens-if-you-replace-state-after-updating-it*/}
### Що відбудеться, якщо замінити стан, перед тим оновивши його {/*what-happens-if-you-replace-state-after-updating-it*/}

Спробуймо ще один приклад. Як гадаєте, що буде в `number` у наступному рендері?

Expand Down Expand Up @@ -246,9 +246,9 @@ React зберігає `42` як остаточний результат і по
* **Функція-оновлювач** (наприклад, `n => n + 1`) додається до черги.
* **Будь-які інші значення** (наприклад, число `5`) додають до черги "замінити на `5`", ігноруючи все, що вже в черзі.

Коли обробник подій завершується, React запускає повторний рендер. Під час нього React обробляє чергу. Функції-оновлювачі запускаються під час рендерингу, тож **функції-оновлювачі повинні бути [чистими](/learn/keeping-components-pure)** й лише *повертати* результат. Не намагайтеся задавати стан зсередини них, чи запускати ще якісь побічні ефекти. У Суворому режимі React намагається запустити кожну функцію-оновлювач двічі (відкидаючи другий результат), щоб допомогти з пошуком помилок.
Коли обробник подій завершується, React запускає повторний рендер. Під час нього React обробляє чергу. Функції-оновлювачі запускаються під час рендерингу, тож **функції-оновлювачі повинні бути [чистими](/learn/keeping-components-pure)** й лише *повертати* результат. Не намагайтеся задавати стан зсередини них чи запускати ще якісь побічні ефекти. У суворому режимі (strict mode) React намагається запустити кожну функцію-оновлювач двічі (відкидаючи другий результат), щоб допомогти з пошуком помилок.

### Домовленості з найменування {/*naming-conventions*/}
### Домовленості про найменування {/*naming-conventions*/}

Прийнято називати аргумент функції-оновлювача за першими літерами відповідної змінної стану:

Expand All @@ -258,11 +258,11 @@ setLastName(ln => ln.reverse());
setFriendCount(fc => fc * 2);
```

Якщо вам подобається розлогіший код, то іншим прийнятим підходом є повторити повну назву змінної стану, так `setEnabled(enabled => !enabled)`, або скористатися префіксом так `setEnabled(prevEnabled => !prevEnabled)`.
Якщо вам подобається розлогіший код, то іншим прийнятим підходом є повторити повну назву змінної стану, як `setEnabled(enabled => !enabled)`, або скористатися префіксом, як `setEnabled(prevEnabled => !prevEnabled)`.

<Recap>

* Задання стану не змінить змінної в наявному рендері, проте зробить запит щодо нового рендеру.
* Задання стану не змінить її змінну в наявному рендері, проте зробить запит щодо нового рендеру.
* React обробляє оновлення стану тоді, коли обробники подій уже закінчили виконання. Це зветься групуванням.
* Щоб оновити якийсь стан кілька разів у одній події, можна скористатися функцією-оновлювачем `setNumber(n => n + 1)`.

Expand All @@ -278,7 +278,7 @@ setFriendCount(fc => fc * 2);

Проте лічильник "Очікування" не поводиться як задумано. Коли натиснути "Придбати", він зменшується до `-1` (що не повинно бути можливим!). А якщо двічі швидко клацнути, то обидва лічильники, здається, поводяться непередбачувано.

Чому так відбувається? Виправмо обидва лічильники.
Чому так відбувається? Виправіть обидва лічильники.

<Sandpack>

Expand Down Expand Up @@ -364,15 +364,15 @@ function delay(ms) {

</Sandpack>

Так можна пересвідчитись, що коли інкрементується чи декрементується лічильник, це відбувається щодо його *останнього* стану, а не того, яким стан був під час клацання.
Так можна пересвідчитись, що коли інкрементується чи декрементується лічильник, це відбувається відповідно до його *останнього* стану, а не того, яким стан був під час клацання.

</Solution>

#### Самостійна реалізація черги стану {/*implement-the-state-queue-yourself*/}
#### Створення власної черги стану {/*implement-the-state-queue-yourself*/}

У цьому завданні ви самі відтворите крихітну частину React з нуля! Це не так важко, як здається.

Погортайте живий зразок. Зверніть увагу на те, що він демонструє **чотири тестові випадки.** Вони відповідають прикладам, які ви бачили на цій сторінці вище. Ваше завдання — реалізувати функцію `getFinalState` так, щоб вона повертала коректний результат для кожного з цих випадків. Якщо реалізувати її коректно, то всі чотири тести пройдуть.
Погортайте попередньо "пісочницю". Зверніть увагу на те, що у ній показані **чотири тестові випадки.** Вони відповідають прикладам, які ви бачили на цій сторінці вище. Ваше завдання — реалізувати функцію `getFinalState` так, щоб вона повертала коректний результат для кожного з цих випадків. Якщо реалізувати її коректно, то всі чотири тести пройдуть.

Ви отримаєте два аргументи: `baseState` — це початковий стан (наприклад, `0`), а `queue` — це масив, що вміщає мішанину з чисел (наприклад, `5`) і функцій-оновлювачів (наприклад, `n => n + 1`) у тому порядку, в якому вони додані.

Expand Down

0 comments on commit c3a03b0

Please sign in to comment.