typescript - Tanstack React Query useMutation altijd Waar in onSuccess
import { TNewServicesProps } from '@/_constants/types';
import api from '@/_libs/api';
import { useMutation, useQueryClient } from '@tanstack/react-query';
const useManageServices = (
method: 'create' | 'update' | 'delete',
item_id?: number | string,
values?: TNewServicesProps
) => {
if ((method === 'update' || method === 'delete') && item_id == null) {
throw new Error(`item_id is required for ${method} method`);
}
const queryClient = useQueryClient();
const { data, error, isPending, mutateAsync, isSuccess } = useMutation({
mutationKey: [`${method}_services`],
mutationFn: async () => {
switch (method) {
case 'create':
return await api
.post(
`/admin/services/`,
JSON.stringify(values !== undefined ? values : {})
)
.then((res) => res.data)
.catch((error) => error.response.data);
case 'update':
return await api
.patch(
`/admin/services/${item_id}/`,
JSON.stringify(values !== undefined ? values : {})
)
.then((res) => res.data)
.catch((error) => error.response.data);
case 'delete':
return await api
.delete(`/admin/services/${item_id}/`)
.then((res) => res.data)
.catch((error) => error.response.data);
default:
throw new Error(`Invalid method: ${method}`);
}
},
//this is always fired, even when response code is 400, 500, etc.
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: ['services'],
});
},
onError: () => {
//should do something but never fired
},
});
return { data, error, mutateStatus: mutateAsync, isPending, isSuccess };
};
export default useManageServices;
Ik ben momenteel aan het experimenteren met react-query in mijn project.
Ik ondervind een probleem met foutafhandeling binnen mijn mutatie.
Wanneer ik het netwerk-tabblad controleer, kan ik zien dat de server reageert met een 400 of 500 statuscode, waarvan ik aannam dat dit ervoor zou zorgen dat axios een fout gooit, waardoor de gedefinieerde onError-functie wordt geactiveerd.
De onSuccess-functie wordt echter altijd aangeroepen.
Wat zou ik over het hoofd kunnen zien? Alvast bedankt.
Antwoord #1
Ik vermoed dat het probleem hier is dat jouw mutatiefunctie de gegooide fouten opvangt voordat de useMutation-hook ze kan afhandelen om daadwerkelijk een opgegeven onError-handler aan te roepen.
Ik vermoed dat je ze ofwel helemaal niet kunt opvangen, of ze gewoon opnieuw kunt gooien nadat ze zijn afgehandeld.
const { data, error, isPending, mutateAsync, isSuccess } = useMutation({
mutationKey: [`${method}_services`],
mutationFn: async () => {
switch (method) {
case 'create':
return await api
.post(
"/admin/services/",
JSON.stringify(values !== undefined ? values : {})
)
.then((res) => res.data);
case 'update':
return await api
.patch(
`/admin/services/${item_id}/`,
JSON.stringify(values !== undefined ? values : {})
)
.then((res) => res.data);
case 'delete':
return await api
.delete(`/admin/services/${item_id}/`)
.then((res) => res.data);
default:
throw new Error(`Invalid method: ${method}`);
}
},
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: ['services'],
});
},
onError: () => {
// ...
},
});
const { data, error, isPending, mutateAsync, isSuccess } = useMutation({
mutationKey: [`${method}_services`],
mutationFn: async () => {
switch (method) {
case 'create':
return await api
.post(
"/admin/services/",
JSON.stringify(values !== undefined ? values : {})
)
.then((res) => res.data)
.catch((error) => {
// error.response.data
throw error;
});
case 'update':
return await api
.patch(
`/admin/services/${item_id}/`,
JSON.stringify(values !== undefined ? values : {})
)
.then((res) => res.data)
.catch((error) => {
// error.response.data
throw error;
});
case 'delete':
return await api
.delete(`/admin/services/${item_id}/`)
.then((res) => res.data)
.catch((error) => {
// error.response.data
throw error;
});
default:
throw new Error(`Invalid method: ${method}`);
}
},
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: ['services'],
});
},
onError: () => {
// ...
},
});
Antwoord #2
Net zoals het antwoord van @Drew Reese aangaf, capture je de fout voortijdig terwijl react query dit al doet. Ik denk dat een vereenvoudigde versie van je code het probleem makkelijker zichtbaar maakt.
mutationFn: async () => {
const response = await api
.delete(`/admin/services/${item_id}/`)
.then((res) => { return res.data })
.catch((error) => {
// you're catching the error and returning the error response
return error.response.data
}
return response; // this will be error.response.data, mutationFn doesn't fail, thus call the onSuccess function.
}
