kabukiman
kabukiman

Reputation: 473

React Query spawns duplicate request with somehow old response from server

Here is my setup:

const ParentComponent = ({ post_id }) => {
  const { data: post } = useGetPost(post_id); // custom hook with useQuery under the hood

  return (
    <div>
      {post.status === 'published' && (
        <div className="margin-bottom">
          <ChildComponent post_id={post_id} />
        </div>
      )}
    </div>
  );
};

const ChildComponent = ({ post_id }) => {
  const { data: post } = useGetPost(post_id);

  return <div>{post.title}</div>;
};

Whenever i change post status to 'published' – React Query spawns two getPost requests, first of which, for some reason, returns previous post status and second returns the right one. Problem is gone if i move post.status === 'published' check to ChildComponent, but it's not an option because of ChildComponent wrapper element ("margin-bottom") inside ParentComponent. Is there something i don't get?

UPDATE:

useGetPost hook:

export const useGetPost = (post_id) => {
  return useQuery<IDiscussion, Error>(
    ['posts', post_id],
    async () =>
      await axios
        .get(`/api/posts/${post_id}`)
        .then((response) => response.data),
  );
};

And my mutation function:

export const useUpdatePost = (post_id) => {
  const queryClient = useQueryClient();

  return useMutation(
    async (data) => await axios.put(`/api/posts/${post_id}`, data),
    {
      onMutate: (data) => {
        // updating react query cache before actual save
        queryClient.setQueryData(['posts', post_id], (oldData) => ({
          ...oldData,
          data,
        }));
      },
      onSuccess: () => {
        queryClient.refetchQueries(['posts', post_id]);
      },
    },
  );
};

Upvotes: 1

Views: 3486

Answers (1)

Marat
Marat

Reputation: 629

ChildComponent mounts after you manually set new query data in "onMutate". The query refetches on mount (default behavior), but mutation is not yet finished, so you see the old status. Then, on mutation success query refetches again and you see updated status.

That is why if your ChildComponent gets mounted unconditionally, you see only one request. You can just get rid of onMutate function and refetch the query only once, after mutation success.

Upvotes: 2

Related Questions