I have a custom hook for the axios calls. I want to use it with useEffect() and also onSumbit() on forms. Right now, the values that are passed to the body
of the customHook, are always empty. How can I fix this?
axios custom hook:
const useHttp = ({ url, method, body = null, headers = null, autoRun = true }) => {
const [response, setResponse] = useState(null);
const [error, setError] = useState("");
const [loading, setloading] = useState(true);
const fetchData = async () => {
api[method](url, headers, body)
.then((res) => {
setResponse(res.data);
})
.catch((err) => {
setError(err);
})
.finally(() => {
setloading(false);
});
};
useEffect(() => {
if (!autoRun) {
return;
}
fetchData();
}, [method, url, body, headers]);
return { response, error, loading, setloading, fetchData };
};
export default useHttp;
usage:
const useAuth = () => {
const [registerFormValues, setRegisterFormValues] = useState({
name: "",
email: "",
password: "",
doctorId: "",
personalNumber: "",
});
const { fetchData } = useHttp({
autoRun: false,
method: "post",
url: "/authentication/register-pacient",
headers: {
"content-type": "application/json",
},
body: JSON.stringify({
name: registerFormValues.name,
email: registerFormValues.email,
password: registerFormValues.password,
doctorId: registerFormValues.doctorId,
personalNumber: registerFormValues.personalNumber,
}),
});
const submitHandlerRegister = async (values) => {
setRegisterFormValues({
name: values.firstName " " values.lastName,
email: values.email,
password: values.password,
doctorId: values.doctorId,
personalNumber: values.personalNumber,
});
console.log("registerFormValues", registerFormValues);
fetchData();
};
return {
submitHandlerRegister,
};
};
export default useAuth;
The submit handler
is used in a formik form. The values
(submit handler parameter, get the right values from the form)
CodePudding user response:
It's almost never a good idea to store same values in two diffrent places. You already have form values in FormikState
, why do you need duplicate this data in useAuth
's state?
When you call setRegisterFormValues
and trying instantly access registerFormValues
, there are still previous values. It will be updated during next render
.
It is more useful to pass up-to-date values directly in fetchData
function:
const fetchData = async (body) => {
api[method](url, headers, body)
.then((res) => {
setResponse(res.data);
})
.catch((err) => {
setError(err);
})
.finally(() => {
setloading(false);
});
};
and usage:
const submitHandlerRegister = async (values) => {
fetchData(values);
};
CodePudding user response:
The working code:
const useHttp = ({ url, method, body = null, headers = null, autoRun = true }) => {
const [response, setResponse] = useState(null);
const [error, setError] = useState("");
const [loading, setloading] = useState(true);
const fetchData = async (body) => {
api[method](url, body)
.then((res) => {
setResponse(res.data);
})
.catch((err) => {
setError(err);
})
.finally(() => {
setloading(false);
});
};
useEffect(() => {
if (!autoRun) {
return;
}
fetchData();
}, [method, url, body, headers]);
return { response, error, loading, setloading, fetchData };
};
export default useHttp;
usage:
const useAuth = () => {
const { fetchData } = useHttp({
autoRun: false,
method: "post",
url: "/authentication/register-pacient",
headers: {
"content-type": "application/json",
},
});
const submitHandlerRegister = async (values) => {
fetchData(values);
};
return {
submitHandlerRegister,
};
};
export default useAuth;