I need help understanding why is that the state is updated in the React Developer Tools state, but not when i console.log
it.
Below is the code:
const [values, setValues] = useState({
lastName: "",
firstName: "",
lastNameHiragana: "",
firstNameHiragana: "",
birthday: "",
sex: "男",
telephone: "",
email: "",
enterDate: "",
companyId: "securityInt(SECI)",
departmentId: "dev",
commissionStatusId: "somestring",
houseStatusId: "somestring",
businessManager: "",
});
const onChange = (e) => {
setValues({ ...values, [e.target.name]: e.target.value });
};
const handleForm = (e) => {
e.preventDefault();
const data = {
firstName: values.firstName,
lastName: values.lastName,
firstNameHiragana: values.firstNameHiragana,
lastNameHiragana: values.lastNameHiragana,
companyId: values.companyId,
birthday: values.birthday,
sex: values.sex === "somestring" ? 0 : 1,
mail: values.email,
telephone: values.telephone,
enterDate: values.enterDate,
departmentId: values.departmentId,
commissioningStatusId: values.commissionStatusId === "somestring" ? 0 : 1,
houseStatusId: values.houseStatusId,
businessManager: values.businessManager,
};
const newErrorMessage = {};
const refresh_token = localStorage.getItem("refresh_token");
const headers = {
headers: {
Authorization: `Bearer ${refresh_token}`,
},
};
for (const name in values) {
const hiraganaRegex = /^[ぁ-ん]+$/;
const telephoneRegex = /^[0-9]{9,11}$/;
const emailRegex = /^[a-z0-9._%+-]+@[a-z0-9.-]+.[a-z]{2,4}$/;
switch (name) {
case "lastName":
case "firstName":
case "birthday":
case "enterDate":
if (!values[name]) {
newErrorMessage[name] = "必須項目です";
}
break;
case "lastNameHiragana":
case "firstNameHiragana":
if (!values[name]) {
newErrorMessage[name] = "必須項目です";
} else if (!hiraganaRegex.test(values[name]) && values[name]) {
newErrorMessage[name] = "ひらがなで入力して下さい。";
}
break;
case "telephone":
if (!values[name]) {
newErrorMessage[name] = "必須項目です";
} else if (!telephoneRegex.test(values[name]) && values[name]) {
newErrorMessage[name] = "9~11桁の半角数字で入力して下さい";
}
break;
case "email":
if (!values[name]) {
newErrorMessage[name] = "必須項目です";
} else if (!emailRegex.test(values[name]) && values[name]) {
newErrorMessage[name] = "メールアドレスの形式が正しくありません";
}
break;
}
}
if (!Object.keys(newErrorMessage).length) {
// Get companies ID
const fetchData = async () => {
if (
typeof values.companyId === "string" &&
typeof values.departmentId === "string"
) {
const [companyRes, departmentRes] = await Promise.all([
axiosInstance.get("/company"),
axiosInstance.get("/department"),
]);
const company = values.companyId.slice(
0,
values.companyId.indexOf("(")
);
const findCompany = companyRes.data.result.find(
(item) => item.name === company
);
const findDepartment = departmentRes.data.result.find(
(item) => item.name === values.departmentId
);
console.log(values.companyId);
console.log(values);
setValues((prevValues) => ({
...prevValues,
companyId: findCompany.id,
departmentId: findDepartment.id,
}));
console.log(values.companyId);
}
};
// Send the information to server
const sendData = async () => {
try {
const response = await axiosInstance.post("/employee", data, {
headers: headers,
});
console.log(response);
} catch (error) {
console.log(error);
}
};
// Call the functions in sequence
(async () => {
await fetchData();
await sendData();
})();
}
setErrorMessage(newErrorMessage);
};
I need to send the correct companyId
and departmentID
, which is OK when I check React Developer Tools state, but when I console.log
the values
, it gives me not the desired result.
Is the below not working, why?
setValues((prevValues) => ({
...prevValues,
companyId: findCompany.id,
departmentId: findDepartment.id,
}));
Is there anything wrong with the code?
Any input would be helpful.
Thank you in advance.
2
Answers
The “useState” set method is asynchronous, hence, the updates are not reflected immediately. You can read this for more clarity.
Since you are using hooks, in your case you need to useEffect hook to see the actual value in the state. You can follow this answer
This behavior happens because the
setValues
function fromuseState
in React is asynchronous. This means it does not immediately alter the state, but schedules the update to happen on the next render. Hence, you can’t rely on the state change to be instantaneous and console.log it right away.The fact that the new state shows up correctly in the React Developer Tools but not in the console.log is because the React Dev Tools read the state after all updates and re-renders have been completed, while your console.log statement is executing before the state has been updated.
In your case, you are trying to log
values
right after callingsetValues
:Since
setValues
is asynchronous,values
has not been updated by the timeconsole.log(values.companyId);
runs.To handle this situation, you might consider using
useEffect
.useEffect
can be used to perform side effects in function components, and it can be used to perform an action when a certain value changes. Here’s how you might use it:This
useEffect
hook will log thecompanyId
whenever it changes, ensuring you’re always logging the latest value.Additionally, your
sendData
function is using thedata
object that was defined beforefetchData
was called and the state was updated. You should move the definition ofdata
into thesendData
function to ensure it uses the updated state: