So I use react-query to handle API requests. Current problem is that when i try to submit form data, post request, mutation state is always idle, and loading is always false. I also use zustand for state management.
This is useSubmitFormData hook. Post request executes as expected, just mutation status and isLoading does not get changed.
export const useSubmitFormData = () => {
const { postDataPlaceholder } = usePlaceholderApi();
// data which is submiting is getting from the store - reducerconst { data, filesToUpload } = useFormDataStore();
const { mutate, status, isLoading } = useMutation(() => postDataPlaceholder({ data }), {
onMutate: () => console.log('onMutate', status),
onSuccess: (res) => console.log(res),
onError: (err) => console.log('err', err),
});
return {
submitForm: mutate,
isLoading,
};
};
Now on FormPage.jsx it is triggered like this:
const { submitForm, isLoading } = useSubmitFormData();
const onSubmit = () => submitForm();
And this is how usePlaceholderApi looks like. It is kind of custom hook in purpose to use axios in combination with interceptors to handle authorization token.
const usePlaceholderApi = () => {
const { post } = usePlaceholderAxios();
return {
postDataPlaceholder: async (data) => post('/posts', { data }),
};
};
export default usePlaceholderApi;
And this is usePlaceholderAxios.
import axios from 'axios';
const usePlaceholderAxios = () => {
axios.interceptors.request.use(async (config) => {
const api = 'https://jsonplaceholder.typicode.com';
if (config.url.indexOf('http') === -1) {
// eslint-disable-next-line no-param-reassign
config.url = `${api}${config.url}`;
}
return config;
});
return {
get: (url, config) => axios.get(url, config),
post: (url, data, config) => axios.post(url, data, config),
};
};
export default usePlaceholderAxios;
Any ideas what could go wrong here ? Am I missing something ? Also tried to call axios directly in mutation, without usePlaceholderApi hook in between, but same outcome.
One possible reason for this could be that the onMutate function is not returning the correct value.
The onMutate function should return a "snapshot" of the current state before the mutation executes, which is then used to roll back the state if the mutation fails. In your code, the onMutate function logs the status value, but it doesn't return anything.
To fix this issue, you should modify the onMutate function to return the current state like this:
const { mutate, status, isLoading } = useMutation(() => postDataPlaceholder({ data }), { onMutate: () => { console.log('onMutate', status); return { data, filesToUpload }; }, onSuccess: (res) => console.log(res), onError: (err) => console.log('err', err), });
This will ensure that the onMutate function returns the current state before the mutation executes, and it should enable the React Query library to update the status and isLoading properties properly.
Additionally, you may want to wrap your submitForm function inside a handleSubmit function to handle form submission events properly. Here's an example:
const { submitForm, isLoading } = useSubmitFormData(); const handleSubmit = (event) => { event.preventDefault(); submitForm(); }; return ( <form onSubmit={handleSubmit}> ... </form> );
This will prevent the form from being submitted through a browser request and instead call your submitForm function.