Blog>
Snippets

Optimistic Update Example with useIsMutating

Demonstrate implementing an optimistic UI update for posting comments, where the comment appears instantly while the mutation request is still processing.
import { useState } from 'react';
import { useMutation, useQueryClient } from '@tanstack/react-query';
Imports necessary hooks from React and React Query.
const postComment = async (commentData) => {
  // API call to post the comment
  return fetch('/api/comments', {
    method: 'POST',
    body: JSON.stringify(commentData),
    headers: {
      'Content-Type': 'application/json',
    },
  }).then((res) => res.json());
};
Defines an asynchronous function to post a comment through an API call.
const usePostComment = () => {
  const queryClient = useQueryClient();
  const { mutate, isLoading } = useMutation(postComment, {
    onMutate: async (newComment) => {
      await queryClient.cancelQueries(['comments']);
      const previousComments = queryClient.getQueryData(['comments']);
      queryClient.setQueryData(['comments'], (oldComments) => [...oldComments, newComment]);
      return { previousComments };
    },
    onError: (err, newComment, context) => {
      queryClient.setQueryData(['comments'], context.previousComments);
    },
    onSettled: () => {
      queryClient.invalidateQueries(['comments']);
    },
  });
  return { mutate, isLoading };
};
Defines a custom hook to post a comment using `useMutation`. Temporarily updates the cache optimistically with `onMutate`, then reverts on error with `onError`, and finally refetches the comments list on settlement with `onSettled`.
const { mutate, isLoading } = usePostComment();

// Usage example inside a component
// On form submit, call mutate with the new comment
mutate({ text: 'New comment!', author: 'User' });
Demonstrates using the custom hook within a component to post a comment.