-
Hello,
export function useDeleteItem() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (id: string) => axios.delete(`/api/items/${id}`),
onSuccess: async () => {
await queryClient.invalidateQueries({ queryKey: ['items'] })
}
})
}
<button
onClick={async () => {
const data = await mutateAsync(id);
navigateOutOfThisPage(data);
}}>
Delete item
</button> The problemWhen doing so, the query invalidation runs before we navigate away from the detail page of the deleted item. Thus it tries to refetch it and receives a 404. Because of the retry, it retries multiple times before abandonning and finally doing the navigation. So the delete button remains multiple seconds in loading state before navigating, which is a bad UX. Non-solutions
export function useDeleteItem({ onBeforeInvalidate } = {}) {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (id: string) => axios.delete(`/api/items/${id}`),
onSuccess: async (data) => {
onBeforeInvalidate?.(data)
await queryClient.invalidateQueries({ queryKey: ['items'] })
}
})
} const { mutateAsync } = useDeleteItem({ onBeforeInvalidate: (data) => {
navigateOutOfThisPage(data);
} })
return <button
onClick={async () => {
await mutateAsync(id);
}}>
Delete item
</button> This is not ideal because the flow is less easy to read: mutation and navigation are in two different places. Also the mutateAsync function is not reusable without navigation in the same component. What'd be more ideal is the solution proposed below. ProposalAdd a callback <button
onClick={async () => {
await mutateAsync(id, {
onBeforeSuccess: (data) => {
navigateOutOfThisPage(data);
}
});
}}>
Delete item
</button> I didn't think of the naming for too long, so the naming and the API probably would need to be challenged (what about errors too?). But generally, this motivates to have more fine grained options at the mutation level to hook into the lifecycle of query then invalidation. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
|
Beta Was this translation helpful? Give feedback.
onBeforeSuccess
is pretty much the same as youronBeforeInvalidate
suggestion, so I think you can build that in user-land just fine.