Что такое оптимистичное обновление и как его реализовать?
Контекст и State managers
Оптимистичное обновление — интерфейс показывает результат действия сразу, не дожидаясь ответа сервера, и откатывает изменение, если запрос завершился ошибкой.
Зачем
Интерфейс кажется мгновенным: лайк, перемещение карточки, отметка задачи не ждут сети.
Схема
- Сохранить текущее состояние для отката.
- Сразу обновить локальные данные.
- Отправить запрос.
- При ошибке вернуть сохранённое состояние и показать сообщение.
- После завершения синхронизироваться с сервером.
const mutation = useMutation({
mutationFn: toggleTodo,
onMutate: async (id) => {
await qc.cancelQueries({ queryKey: ['todos'] });
const previous = qc.getQueryData(['todos']);
qc.setQueryData(['todos'], (old) =>
old.map((t) => (t.id === id ? { ...t, done: !t.done } : t)),
);
return { previous };
},
onError: (err, id, ctx) => qc.setQueryData(['todos'], ctx.previous),
onSettled: () => qc.invalidateQueries({ queryKey: ['todos'] }),
});Когда не стоит
Для платежей и необратимых операций лучше дождаться подтверждения. Откат должен быть заметным пользователю.
Коротко для собеседования
Сначала обновляем интерфейс, потом подтверждаем у сервера, при ошибке откатываем. В React Query это onMutate, onError и onSettled.