Reputation: 561
I have two queries
one for single user
const { data: user, error, isLoading } = useQuery<User>(
['users', userId],
() => axios.get('/users/' + userId).then((res) => res.data),
{
retry: false,
}
);
and for list of all users
const { data: users, error, isLoading } = useQuery<User[]>(
['users'],
() => axios.get('/users').then((res) => res.data),
{
retry: false,
}
);
Now I have delete mutation
const deleteMutation = useMutation(
() => axios.delete('api/v1/users/' + userId),
{
onSuccess: () => {
toast.success(`successfully deleted`);
resetForm();
},
onError: (error: AxiosError) => {
toast.error(`Failed to delete ${error.message}`);
resetForm();
},
onSettled: () => {
queryClient.invalidateQueries({ queryKey: ['users'] });
},
}
);
Issue is that after deletion it invalidates both list of users and single user that couses unnesesary 404.
What is proper way to prevent invalidating single user query after delete mutation?
Upvotes: 1
Views: 182
Reputation: 187222
You don't "delete" a query. If you are still rendering a component with a query that is asking for a now deleted resource, then it needs that (now deleted) data in order to render. So that's not going to work.
You need to make sure that component that needs that deleted resource is no longer is rendering. You should do this by updating state somehow.
Say this button was in an "edit user" modal dialog. Then you'd have a state like:
const [editingUser, setEditingUser] = useState<User | null>(null)
And you'd show the component that asks for the user record like this:
{editingUser && <UserModal user={editingUser} />}
Then you set the state that hides that element at the same point where you invalidate the query.
const deleteMutation = useMutation(
() => axios.delete('api/v1/users/' + userId),
{
//...
onSettled: () => {
setEditingUser(null)
queryClient.invalidateQueries({ queryKey: ['users'] });
},
}
);
Now when the next render happens the query for the single user record never happens, and there's no problem.
Upvotes: 1