Optimistic UI Updates with TanStack Router
Detail how to implement optimistic UI updates in a data mutation scenario, including handling potential errors and reverting the UI to its previous state if the update fails.
import { useMutation, useQueryClient } from 'react-query';
First, import `useMutation` and `useQueryClient` from react-query to handle the mutation and to access the query client for cache updates.
const updateData = async (newData) => {
// Replace with your update logic, typically an API call
return fetch('/api/data', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(newData),
}).then(res => res.json());
};
Define the `updateData` function which makes an API call to update your data. This function should return a promise with the updated data.
const useOptimisticUpdate = () => {
const queryClient = useQueryClient();
return useMutation(updateData, {
onMutate: async (newData) => {
await queryClient.cancelQueries('data');
const previousData = queryClient.getQueryData('data');
queryClient.setQueryData('data', newData);
return { previousData };
},
onError: (err, newData, context) => {
queryClient.setQueryData('data', context.previousData);
},
onSettled: () => {
queryClient.invalidateQueries('data');
}
});
};
Define a custom hook `useOptimisticUpdate` using `useMutation` to perform the update. This hook temporarily updates the query cache optimistically, rolls back on error, and finally, refetches the data for consistency.
const { mutate } = useOptimisticUpdate();
// Call this function with the new data to update optimistically
mutate(newData);
Use the `useOptimisticUpdate` hook to get the `mutate` function, which you can then call with the new data to perform an optimistic UI update.