Optimistic Updates with useMutation
Illustrate how to use the useMutation hook to perform optimistic updates, by temporarily updating the UI before the mutation's success confirmation from the server.
import { useMutation, useQueryClient } from 'react-query';
First, import useMutation and useQueryClient from react-query.
const updateTodo = async (todo) => {
// API call to update the todo, replace URL with your API endpoint
const response = await fetch('https://your-api/todos/' + todo.id, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(todo),
});
return response.json();
};
Define the async function that will be used to send the updated todo to the server. This example uses the Fetch API to send a PUT request.
const useUpdateTodo = () => {
const queryClient = useQueryClient();
return useMutation(updateTodo, {
onMutate: async (newTodo) => {
// Cancel any outgoing refetches (so they don't overwrite our optimistic update)
await queryClient.cancelQueries('todos');
// Snapshot the previous value
const previousTodos = queryClient.getQueryData('todos');
// Optimistically update to the new value
queryClient.setQueryData('todos', oldTodos => {
return oldTodos.map(todo => todo.id === newTodo.id ? { ...todo, ...newTodo } : todo);
});
return { previousTodos };
},
onError: (err, newTodo, context) => {
// Rollback to the previous value
queryClient.setQueryData('todos', context.previousTodos);
},
onSettled: () => {
// After mutation or error, refetch the todos query
queryClient.invalidateQueries('todos');
},
});
};
Define a custom hook `useUpdateTodo` using the `useMutation` hook. This hook sets up optimistic updates for updating a todo. Before the mutation is sent to the server, it optimistically updates the UI. If the mutation fails, it rolls back the change.
const { mutate: updateTodo } = useUpdateTodo();
Use the custom hook `useUpdateTodo` in your component to get the mutate function. This function is used to trigger the mutation.
<button onClick={() => updateTodo({ id: todo.id, title: 'Updated Todo' })}>Update Todo</button>
Example of using the `updateTodo` mutate function on a button click event to update a todo's title. Replace `todo.id` and `'Updated Todo'` with your actual data.