advanced
Optimistic UI
Показывайте ожидаемый результат mutation до подтверждения сервером, с откатом и обработкой конфликтов.
Optimistic UI применяет ожидаемый результат mutation до подтверждения сервером. Пользователь видит мгновенный отклик; при ошибке откатываемся к предыдущему снимку кэша и показываем ошибку.
useMutation({
mutationFn: updateTodo,
onMutate: async (patch) => {
await queryClient.cancelQueries({ queryKey: ['todos'] });
const previous = queryClient.getQueryData(['todos']);
queryClient.setQueryData(['todos'], (old) => mergeTodo(old, patch));
return { previous };
},
onError: (_err, _patch, ctx) => {
queryClient.setQueryData(['todos'], ctx.previous);
},
onSettled: () => queryClient.invalidateQueries({ queryKey: ['todos'] }),
});
Нужен идемпотентный UX или разрешение конфликтов, когда серверная истина расходится. Отключайте double-submit, toast при откате, телеметрия доли ошибок.
Компромисс: мгновенная perceived latency против сложности UX отката и разрешения конфликтов при расхождении с сервером.
На интервью: зачем cancel in-flight queries при optimistic update; почему onSettled всё равно refetch.
Типовые ошибки: optimistic без снимка, необратимые действия (оплата) «оптимистично», UI скрывает ошибку после rollback.
Чеклист:
- Снимок перед optimistic записью.
- cancelQueries против гонок перезаписи.
- Откат при ошибке с ясным UX.
- Сверка с сервером в onSettled.