在下面的代码中,除非我将先前的状态传递给状态设置调用 ('setForm'),否则表单不会正确更新。
要查看它的实际效果,请按原样运行代码,控制台将打印“true”,表明它有效。那是使用“validate1”函数。如果将其替换为“validate2”(不使用以前的状态),则无法打印“true”。
似乎在 validate2 中,由于这些调用的异步性质,第二个 setForm 调用覆盖了第一个 setForm 调用的 form.long 状态。但为什么 validate1 有效?为什么使用以前的状态会导致它工作?有关此行为的任何文档都会非常有帮助。
(我可以通过设置一个 setForm 来设置两个字段来使 validate2 工作,但是下面的代码被设计来显示可以调用 setForm 的两种方式的差异,有和没有以前的状态。)
const {useState, useEffect} = React;
function LoginForm() {
const [form, setForm] = useState({
username: "",
password: "",
long: null
});
useEffect(() => {
console.log(form.long);
}, [form.long]);
const validate1 = (e) => {
e.preventDefault();
setForm((prevState) => ({
...prevState,
long: form.password.length >=3 ? true : false
}));
setForm((prevState) => ({
...prevState,
username: "*****"
}));
};
const validate2 = (e) => {
e.preventDefault();
setForm({
...form,
long: form.password.length >=3 ? true : false
});
setForm({
...form,
username: "*****"
});
};
const updateField = (e) => {
setForm({
...form,
[e.target.name]: e.target.value
});
};
return (
<form onSubmit={validate1}>
<label>
Username:
<input value={form.username} name="username" onChange={updateField} />
</label>
<br />
<label>
Password:
<input
value={form.password}
name="password"
type="password"
onChange={updateField}
/>
</label>
<br />
<button>Submit</button>
</form>
);
}
// Render it
ReactDOM.render(
<LoginForm/>,
document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="react"></div>