We can use the onMutate
callback:
const [createPost, createPostInfo] = useMutation( (values) => axios.post("/api/posts", values), { onMutate: (values) => { // Used to prevent outgoing requests are in flight // from causing race conditions. queryCache.cancelQueries("posts"); const oldPosts = queryCache.getQueryData("posts"); queryCache.setQueryData("posts", (oldPosts) => { return [ ...oldPosts, { ...values, id: Date.now(), }, ]; }); // required for rollback. return () => queryCache.setQueryData("posts", oldPosts); }, onError: (error, values, rollback) => { // window.alert(error.response.data.message) // Rollback if required if (rollback) { rollback(); } }, onSettled: () => queryCache.invalidateQueries("posts"), } );
The rollback
call is used to help rollback to the previous state on an error.
Whatever is returned from the onMutate
becomes available for our onError
as the third value.
Here is the example as code:
const [savePost, savePostInfo] = useMutation( (values) => axios.patch(`/api/posts/${values.id}`, values).then((res) => res.data), { onMutate: (values) => { queryCache.cancelQueries(["post", String(values.id)]); const oldPost = queryCache.getQueryData(["post", String(values.id)]); queryCache.setQueryData(["post", String(values.id)], values); return () => queryCache.setQueryData(["post", String(values.id)], oldPost); }, onError: (error, values, rollback) => { if (rollback) { rollback(); } }, onSuccess: (data, values) => { queryCache.setQueryData(["post", String(values.id)], data); }, onSettled: (data, error, values) => { queryCache.invalidateQueries(["post", String(values.id)]); }, } );