Syncing Local and Server State with Optimistic Updates
Explain how to implement optimistic updates in React Query, allowing UI changes to reflect immediately before confirming changes on the server-side, and reverting if an error occurs.
import { useMutation, useQueryClient } from 'react-query';
const updateSection = async (sectionData) => {
// Here you would make your API call to update the section
return fetch('/api/section/update', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(sectionData),
}).then((res) => res.json());
};
This code defines an asynchronous function to update a section. It uses the Fetch API to send a POST request to the server. Replace '/api/section/update' with your actual endpoint.
const useOptimisticUpdateSection = () => {
const queryClient = useQueryClient();
return useMutation(updateSection, {
onMutate: async (newSection) => {
await queryClient.cancelQueries('sections');
const previousSections = queryClient.getQueryData('sections');
queryClient.setQueryData('sections', (old) => [...old, newSection]);
return { previousSections };
},
onError: (err, newSection, context) => {
queryClient.setQueryData('sections', context.previousSections);
},
onSettled: () => {
queryClient.invalidateQueries('sections');
},
});
};
This custom hook uses React Query's useMutation along with an optimistic update pattern: - onSave: Cancel ongoing fetches for sections and get the previous state. Temporarily update the state with the new section data optimistically before the mutation is confirmed. - onError: If the mutation fails, rollback to the previous sections state. - onSettled: After the mutation is either successful or unsuccessful, refetch the sections data to ensure it’s synchronized with the server.