Как сделать оптимистичное обновление интерфейса с откатом при ошибке?
- Что такое optimistic update?
Оптимистичное обновление показывает результат действия сразу, не дожидаясь сервера (лайк, отметка задачи), — интерфейс кажется мгновенным. В TanStack Query: в onMutate отменить текущие запросы этого ключа, сохранить прежние данные, записать новые через setQueryData и вернуть снимок; в onError — откатить из снимка и показать ошибку; в onSettled — инвалидировать, чтобы сверить с сервером. В React 19 для простых случаев есть useOptimistic.
- Подходит для действий с высокой вероятностью успеха
- Платежи и необратимые операции — не оптимистично
- Пользователь должен увидеть, что действие не удалось
А ещё Без отмены запросов в onMutate старый ответ может затереть оптимистичные данные
Подробно
useMutation({
mutationFn: api.toggleDone,
onMutate: async (id) => {
await qc.cancelQueries({ queryKey: ["todos"] });
const prev = qc.getQueryData<Todo[]>(["todos"]);
qc.setQueryData<Todo[]>(["todos"], t => t!.map(x => x.id === id ? { ...x, done: !x.done } : x));
return { prev };
},
onError: (_e, _id, ctx) => qc.setQueryData(["todos"], ctx?.prev),
onSettled: () => qc.invalidateQueries({ queryKey: ["todos"] }),
});Что хотят услышать
- Показ результата до ответа сервера.
- onMutate со снимком, откат в onError, сверка в onSettled.
- Когда не применять.
Проверьте себя
Один верный вариант. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✗Оптимистично проводить и платежи: показывать успех до ответа платёжного шлюза
- ✗При ошибке оставлять оптимистичные данные, чтобы не расстраивать пользователя сообщением
- ✓В onMutate обновить кэш со снимком, в onError откатить, в onSettled сверить
- ✗Отменять текущие запросы в onMutate не нужно — старый ответ не перезапишет кэш
Связанные вопросы
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.