So I have this component which is used for forms handling:
import React, { useState } from "react";
export const useForm = (callback: any, initialState = {}) => {
const [values, setValues] = useState(initialState);
const onChange = (event: React.ChangeEvent<any>) => {
setValues({ ...values, [event.target.name]: event.target.value });
};
const onSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
await callback();
};
return {
onChange,
onSubmit,
setValues,
values,
};
}
in my component, I use it like this:
const { id } = useParams();
const initialState = {
field1: "",
field2: "",
....
}
const { onChange, onSubmit, setValues, values } = useForm(
submitData,
initialState
);
useEffect(
() => {
if(id) {
getData().then((response) => {
setValues(response);
console.log(response);
console.log(values);
});
}
}
,[]);
async function getData() {
return await (await instance.get(url)).data;
}
The two console.logs in the useEffect hook are different and I don't understand why. I used setValues so I expect the components to be re-drawn and the "values" variable to be updated with the values from the response, but it still has the values from the initialState for some reason.
Why is that happening and how can I fix it?
CodePudding user response:
The change of state using setState
hook will not be reflected synchronously.
This is taken from react docs:
setState() does not always immediately update the component. It may batch or defer the update until later. This makes reading this.state right after calling setState() a potential pitfall. Instead, use componentDidUpdate or a setState callback (setState(updater, callback)), either of which are guaranteed to fire after the update has been applied.