Synchronizing optimistic updates across components
Explain how to keep the application state consistent across different components after performing optimistic updates using React Query's query invalidation features.
import { useMutation, useQueryClient } from 'react-query';
const updateUserProfile = async (userData) => {
// Simulate a PATCH request to update user data on the server
return fetch('/api/user', {
method: 'PATCH',
body: JSON.stringify(userData),
headers: { 'Content-Type': 'application/json' },
}).then(res => res.json());
};
This code defines an asynchronous function `updateUserProfile` to update user data on the server by making a PATCH request. It leverages the fetch API for making HTTP requests.
const useOptimisticUpdateUser = () => {
const queryClient = useQueryClient();
return useMutation(updateUserProfile, {
onMutate: async (newData) => {
await queryClient.cancelQueries('user');
const previousUserData = queryClient.getQueryData('user');
queryClient.setQueryData('user', prev => ({ ...prev, ...newData }));
return { previousUserData };
},
onError: (err, newData, context) => {
queryClient.setQueryData('user', context.previousUserData);
},
onSettled: () => {
queryClient.invalidateQueries('user');
},
});
}
This hook `useOptimisticUpdateUser` uses React Query's `useMutation` to optimistically update user data across components. `onMutate` saves the previous state, optimistically updates the cache with the new data, and `onError` rolls back to the previous state in case of an error. After the mutation is settled, the `queryClient.invalidateQueries('user')` ensures all components using this query refetch their data to stay synchronized.