Optimistic updates improve perceived performance by updating the UI before the server confirms the change. Libraries like React Query (TanStack Query) simplify this. Use the onMutate option in useMutation to:
- Cancel relevant ongoing queries.
- Snapshot the current state.
- Update the local cache optimistically.
- Return the snapshot.
- Use onError to roll back the cache using the snapshot if the mutation fails. Use onSettled to refetch/invalidate queries ensuring eventual consistency.
Using React Query’s useMutation:
const mutation = useMutation(updateItem, { onMutate: async (newItem) => { await queryClient.cancelQueries('items'); const previousData = queryClient.getQueryData('items'); queryClient.setQueryData('items', (old) => [...old, newItem]); return { previousData }; }, onError: (err, newItem, context) => { queryClient.setQueryData('items', context.previousData); }, onSettled: () => { queryClient.invalidateQueries('items'); },
});