我需要帮助理解为什么在React Developer Tools状态下更新状态,而不是在i console.log
时更新。下面是代码:
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);
};
我需要发送正确的companyId
和departmentID
,当我检查React Developer Tools状态时,这是可以的,但是当我console.log
values
时,它给我的不是想要的结果。下面是不是不工作了,为什么?
setValues((prevValues) => ({
...prevValues,
companyId: findCompany.id,
departmentId: findDepartment.id,
}));
密码有什么问题吗?任何输入都将是有帮助的。
先谢谢你。
2条答案
按热度按时间b5buobof1#
在React中,
useState
中的setValues
函数是异步的,这意味着它将状态更新安排在下一次渲染时进行,而不是立即进行。因此,如果您尝试在使用setValues
更新状态后立即记录它,您可能会遇到以前的状态,而不是更新后的状态。然而,在React Developer Tools中,状态是在完成所有更新和重新渲染之后显示的。因此,即使
console.log
可能会显示以前的状态,React开发人员工具也会正确显示更新后的状态。可以在代码中观察到此行为:
这里,由于
setValues
的异步特性,console.log(values.companyId);
在状态更新之前被执行。要解决这种情况,可以使用
useEffect
钩子,它在函数组件中启用副作用,并在特定值更改时执行操作。以下是您可能使用它的方式:这个
useEffect
钩子将在companyId
发生变化时记录它,因此总是反映最新的值。此外,您的
sendData
函数正在使用data
对象,该对象是在调用fetchData
并更新状态之前定义的。您应该在sendData
函数中定义data
,以确保使用更新后的状态:现在,如果您将
data
对象放在sendData
函数中,则在调用该函数时,它将始终使用当前状态。但是,请注意,由于
useState
钩子的异步特性,在调用sendData
时状态可能不会立即更新,这可能导致data
对象没有更新的值。更好的方法是从
fetchData
函数返回更新后的状态,并将其作为参数传递给sendData
函数。下面是如何做到这一点:在此调整后的代码中,
newValues
存储更新后的状态,我们将其直接传递给sendData
,确保sendData
使用正确的更新状态。zzoitvuj2#
“useState”set方法是异步的,因此,更新不会立即反映出来。您可以read this以获得更清晰的效果。
因为你使用的是钩子,在你的例子中你需要使用Effect钩子来查看状态中的实际值。您可以关注this answer