学习通过 React 状态驱动每一个表单字段,从而校验并提交可靠的数据。
在 Kodokon 中打开本课在 React 中,当每个字段都是受控的时,表单就变得可预测:显示的值来自组件的状态,每一次按键都通过 onChange 来更新该状态。DOM 不再是数据的唯一来源,你的状态才是。实际操作中,你把 value 属性绑定到一个状态变量上,并提供一个调用更新函数的处理器。
import { useState } from "react";
function EmailField() {
const [email, setEmail] = useState("");
return (
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
);
}真实的表单很少只有一个字段。与其堆叠多个 useState 调用,不如把这些值归并到一个对象中,并编写一个通用处理器。每个字段的 name 属性必须与对象的某个键完全对应:正是它告诉处理器要更新哪个属性。
const [form, setForm] = useState({
username: "",
password: "",
});
function handleChange(e) {
const { name, value } = e.target;
setForm((prev) => ({ ...prev, [name]: value }));
}剩下的就是提交了。默认情况下,提交表单时浏览器会重新加载页面:请在 onSubmit 处理器的开头调用 e.preventDefault()。这里也是在发送数据前校验数据的恰当位置,因为整个表单状态已经就在手边。
function handleSubmit(e) {
e.preventDefault();
if (form.username.trim() === "") {
alert("Username is required.");
return;
}
console.log("Submitting:", form);
}
return (
<form onSubmit={handleSubmit}>
<input
name="username"
value={form.username}
onChange={handleChange}
/>
<button type="submit">Create account</button>
</form>
);<input> 传了 value={email},却没有提供 onChange。会发生什么?onSubmit 处理器中,e.preventDefault() 有什么用?