Skip to main content

Що таке "optimistic update"?

Що таке "optimistic update"

Optimistic update (оптимістичне оновлення) - це підхід, за якого UI оновлюється відразу, ще до того, як сервер підтвердив зміну даних.

Тобто застосунок оптимістично припускає, що операція на сервері завершиться успішно, і оновлює інтерфейс миттєво, щоб користувач не відчував затримку.


Приклад без оптимістичного оновлення:

javascript
async function handleLike(postId) { await fetch(`/api/posts/${postId}/like`, { method: "POST" }); refetch(); // чекаємо відповідь від сервера, потім оновлюємо UI }

Мінуси:

  • Кнопку «лайк» натиснуто → але UI не змінився, поки не прийшла відповідь.
  • Користувач відчуває затримку 300-500 мс (або більше при поганій мережі).
  • Відчувається "загальмований" застосунок.

Приклад з optimistic update:

javascript
const queryClient = useQueryClient(); async function handleLike(postId) { // 1. Одразу оновлюємо UI локально queryClient.setQueryData(['post', postId], (old) => ({ ...old, likes: old.likes + 1, isLiked: true, })); try { // 2. Надсилаємо запит на сервер await fetch(`/api/posts/${postId}/like`, { method: 'POST' }); } catch (err) { // 3. Якщо сервер відповів помилкою - відкочуємо зміни queryClient.invalidateQueries(['post', postId]); } }

Користувач бачить оновлення миттєво - навіть без відповіді від сервера. Коли сервер підтвердить - усе вже синхронізовано. Якщо сервер відповість помилкою - дані відкочуються до актуального стану.


Візуальний сценарій

ПодіяЩо бачить користувачЩо відбувається в коді
Натиснув кнопку "лайк"лайк став активнимsetQueryData() оновлює кеш негайно
Сервер отримав запитнічого не змінюється в UIfetch() виконується у фоні
Сервер відповів 200 OKусе залишається як єкеш лишається актуальним
Сервер відповів 500лайк зникаєвідкат (invalidateQueries або rollback)

Чому це важливо

1. Миттєвий відгук

Користувач відчуває, що застосунок працює "у реальному часі"

  • без затримок, навіть якщо мережа повільна.

2. Плавний UX

Інтерфейс реагує одразу, без "мерехтіння" лоадерів. Оптимістичні оновлення особливо важливі в інтерактивних діях:

  • лайки,
  • коментування,
  • голосування,
  • зміни імені, статусу, позиції елемента в списку.

3. Незалежність від мережі

Якщо запит не пройшов - можна відкотити локальні зміни. Користувач не втрачає контекст (він бачить, що дія "скасувалася").


Як реалізується на практиці

1. React Query

javascript
import { useMutation, useQueryClient } from '@tanstack/react-query'; function useLikePost() { const queryClient = useQueryClient(); return useMutation({ mutationFn: (postId) => fetch(`/api/posts/${postId}/like`, { method: 'POST' }), // 1. Оптимістично оновлюємо кеш onMutate: async (postId) => { await queryClient.cancelQueries(['post', postId]); const prevPost = queryClient.getQueryData(['post', postId]); queryClient.setQueryData(['post', postId], (old) => ({ ...old, likes: old.likes + 1, isLiked: true, })); // 2. Повертаємо дані для rollback return { prevPost }; }, // 3. Якщо помилка - відкочуємо onError: (err, postId, context) => { queryClient.setQueryData(['post', postId], context.prevPost); }, // 4. Після успіху - оновлюємо або інвалідуємо onSettled: (postId) => { queryClient.invalidateQueries(['post', postId]); }, }); }

onMutate → локальне оновлення onError → відкат onSettled → фінальне оновлення/валідація


2. SWR (Vercel)

javascript
import useSWR, { mutate } from 'swr'; function likePost(postId) { // оптимістично збільшуємо кількість лайків mutate(`/api/posts/${postId}`, async (data) => { await fetch(`/api/posts/${postId}/like`, { method: 'POST' }); return { ...data, likes: data.likes + 1, isLiked: true }; }, { optimisticData: { ...data, likes: data.likes + 1, isLiked: true }, rollbackOnError: true }); }

3. Redux Toolkit Query

RTK Query також дозволяє тимчасово оновлювати кеш локально:

javascript
const [updatePost] = useUpdatePostMutation(); updatePost(newData) .unwrap() .then(() => dispatch(api.util.invalidateTags(['Post']))) .catch(() => revertLocalState());

4. Типові кейси для optimistic update

ДіяЩо оновлюємо локально
ЛайкЗбільшуємо лічильник лайків
Додавання коментаряДодаємо коментар у список
Видалення елементаВидаляємо з UI до відповіді сервера
Зміна профілюЗмінюємо ім'я/аватар локально
Зміна порядкуПереставляємо елементи локально
Оплата / замовленняПозначаємо "створено" до підтвердження сервера

Підсумок

Що робить Optimistic UpdateЧому важливо
Оновлює UI до відповіді серверамиттєвий відгук
Покращує UX і швидкість сприйняттянемає "затримки" при взаємодії
Синхронізується при успіхуUI і сервер лишаються узгодженими
Робить відкат при помилцінадійно при нестабільній мережі
Скорочує кількість станів loadingінтерфейс відчувається "живим"

Коротко:

Optimistic update - це спосіб зробити інтерфейс миттєво відгукливим: UI оновлюється відразу, оптимістично припускаючи успіх, а якщо сервер повернув помилку - React відкочує зміни.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.