Ця стаття розглядає пакетну обробку в React. Завдяки точному налаштуванню керування станом і рендерингом у React, можна покращити досвід користувача (UI/UX). У цій статті ми детально розглянемо, чому React використовує пакетну обробку, логіку, що стоїть за нею, і як її реалізувати.
Що таке пакетна обробка в React?
Пакетна обробка — це механізм, який обробляє кілька оновлень стану одночасно. Зокрема, він відкладає оновлення інтерфейсу, поки весь код всередині обробника подій не буде виконано.
Є два основні переваги пакетної обробки:
- Покращення продуктивності
Найбільша перевага пакетної обробки — це покращення продуктивності. Обробляючи кілька оновлень стану в пакетах, React може зменшити кількість непотрібних повторних рендерів, що робить додаток більш чутливим.
Наприклад, якщо в обробнику подій є 100 оновлень стану, React може виконати всі їх в одну операцію DOM.
2. Узгоджений стан інтерфейсу
Оскільки кілька оновлень стану застосовуються одночасно, пакетна обробка допомагає підтримувати узгоджений стан інтерфейсу. Це покращує досвід користувача і запобігає несподіваному мерехтінню інтерфейсу або несумісностям.
Тепер давайте розглянемо конкретний приклад. Ось React компонент, який має збільшити лічильник на 3 при натисканні кнопки:
import { useState } from 'react';
export default function Counter() {
const [number, setNumber] = useState(0);
return (
<>
{number}
{ setNumber(number + 1); setNumber(number + 1); setNumber(number + 1); }}>+3 ) } ```
**Очікувана поведінка:** Натискання кнопки збільшує число на 3.
**Фактична поведінка:** Число збільшується лише на 1!
## Чому це відбувається?
Це трапляється через **пакетну обробку в React**. Коли React рендерить компонент, він робить **знімок** стану. Усі обчислення всередині функції, включаючи властивості JSX, обробники подій і локальні змінні, використовують цей знімок стану.
Ось що відбувається крок за кроком:
1. Коли кнопка натискається, створюється знімок стану (`number = 0`).
2. Кожен виклик `setState` ґрунтується на цьому ж знімку (тобто, `number` завжди `0`).
3. Як результат, лише останнє `setNumber(number + 1)` насправді застосовується, збільшуючи число лише на 1.

## Як це виправити?
Щоб правильно збільшити число на 3, потрібно використовувати **функцію-оновлювач**, а не безпосередньо змінювати стан.
## Рішення: Використання функції-оновлювача
Ми можемо передати функцію зворотного виклику до `setNumber`, ось так:
import { useState } from 'react';
export default function Counter() {
const [number, setNumber] = useState(0);
return (
<>
{number}
{ setNumber(n => n + 1); setNumber(n => n + 1); setNumber(n => n + 1); }}>+3 ) } ```
Чому це працює?
Коли ми використовуємо функцію-оновлювач, оновлення ставляться в чергу, і кожне оновлення має доступ до найновішого значення стану в черзі. Це гарантує, що кожен виклик setNumber
ґрунтується на останньому стані.
Пояснення:
- Перше
setNumber(n => n + 1)
виконується зn = 0
, тому новий стан стає 1. - Друге
setNumber(n => n + 1)
виконується зn = 1
, оновлюючи стан до 2. - Третє
setNumber(n => n + 1)
виконується зn = 2
, встановлюючи стан на 3.
Використовуючи функцію-оновлювач, кожне оновлення правильно відображає попередній стан, гарантуючи очікувану поведінку.
Висновок
Розуміння тонких поведінок, таких як пакетна обробка в React, є важливим, оскільки вони можуть призвести до несподіваних помилок або значних покращень UI/UX. Оскільки React має велику офіційну документацію, доцільно регулярно переглядати її, щоб поглибити своє розуміння. 🚀
Перекладено з: Understanding Batch Processing in React