Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як зробити оптимістичне оновлення форми через useOptimistic і що відбувається при помилці?

Оптимістичне оновлення - показати результат дії одразу, не чекаючи відповіді сервера: повідомлення з'являється в чаті миттєво, лайк зараховується одразу. Якщо сервер відмовив - повернути як було.

useOptimistic(value, reducer?) (React 19) повертає тимчасовий стан, що діє, поки виконується дія:

import { useOptimistic, useState } from 'react';

function Comments({ initialComments }) {
  const [comments, setComments] = useState(initialComments);
  const [optimisticComments, addOptimistic] = useOptimistic(
    comments,
    (current, text) => [...current, { id: `temp-${Date.now()}`, text, sending: true }],
  );

  async function addComment(formData) {
    const text = formData.get('text');
    addOptimistic(text);                         // одразу на екрані
    try {
      const saved = await api.createComment(text);
      setComments((list) => [...list, saved]);   // справжні дані
    } catch {
      toast.error('Коментар не надіслано');      // оптимістичний стан зникне сам
    }
  }

  return (
    <>
      <ul>
        {optimisticComments.map((c) => (
          <li key={c.id} style={{ opacity: c.sending ? 0.6 : 1 }}>{c.text}</li>
        ))}
      </ul>
      <form action={addComment}>
        <input name="text" />
      </form>
    </>
  );
}

Як це працює:

  • поки дія виконується, optimisticComments = результат reducer (чи значення, передане в сеттер);
  • коли дія завершилася, React повертає optimisticComments до value - тобто до comments;
  • успіх: comments уже містить збережений коментар - користувач бачить справжні дані;
  • помилка: comments не змінено - тимчасовий коментар просто зникає. Ручного «відкату» не треба.

Умови:

  • сеттер оптимістичного стану треба викликати всередині дії (<form action>, startTransition). Поза нею React попередить, і оптимістичне значення лише мигне;
  • reducer має бути чистим.

Що враховувати в UX:

  • позначати непідтверджені дані (напівпрозорість, «надсилається»), щоб користувач розумів, що вони ще не збережені;
  • повідомляти про невдачу - тихе зникнення коментаря гірше за помилку;
  • не застосовувати для незворотних дій (оплата, видалення без кошика): оптимістичний «успіх» там вводить в оману;
  • тимчасові ключі - згенерований id, щоб React не переплутав оптимістичний елемент зі справжнім.

Докладніше в документації: useOptimistic

Схожі питання