原生 input 自己维护内部状态(用户输入直接显示)。受控组件把它接管: setMsg(e.target.value)} /> ——数据变化经状态绕一圈再回显给输入框。单向数据流因此贯穿到表单底层:界面上的一切都是状态的映射。
受控化的收益:输入校验(onChange 里过滤非法字符)、格式化(自动加千分位/空格)、提交前强制约束。多字段表单的最佳实践:状态用对象 + name 属性统一处理,或直接上 react-hook-form(非受控方案 + 校验生态)。
function Form() {
const [form, setForm] = useState({ name: '', phone: '' });
// 一个通用 handler 处理所有字段
const change = e => setForm(prev => ({
...prev,
[e.target.name]: e.target.value,
}));
// 手机号只允许数字(校验/过滤在受控里很自然)
const phoneChange = e =>
setForm(prev => ({ ...prev, phone: e.target.value.replace(/\D/g, '') }));
return (
<form onSubmit={e => { e.preventDefault(); console.log(form); }}>
<input name="name" value={form.name}
onChange={change} />
<input name="phone" value={form.phone}
onChange={phoneChange} />
<button>提交</button>
</form>
);
}