本章属于 React 教程的核心路线。建议先通读概念模型,再手写最小示例,最后用练习验证自己能否独立复现。
本章目标
本章掌握受控组件、onChange、文本输入、checkbox、submit handler、表单校验,以及非受控组件的使用边界。
阅读本章时,请把每个 API 放回“数据如何变成界面、用户操作如何改变数据”的主线中理解。React 的学习重点不是背诵语法,而是建立可预测的渲染模型。
- 识别本章概念在真实组件中的位置
- 能写出一个最小可运行示例
- 能解释常见错误为什么发生
概念模型
受控组件把输入值放进 React state,界面显示由 state 决定;非受控组件把值留在 DOM 中,需要时通过 ref 读取。
你可以把 React 程序看成一棵由组件组成的元素树。每次输入数据、状态或外部系统发生变化,React 会重新计算需要展示的 React element,再用高效的方式更新浏览器中的 DOM。
最小示例
一个课程报名表同时包含文本框、复选框、提交处理和校验信息。
import { useRef, useState } from "react";
export function SignupForm() {
const [name, setName] = useState("");
const [accepted, setAccepted] = useState(false);
const fileRef = useRef<HTMLInputElement>(null);
const error = name.trim() === "" ? "请输入姓名" : "";
function handleSubmit(event: React.FormEvent) {
event.preventDefault();
if (error) return;
console.log({ name, accepted, file: fileRef.current?.files?.[0]?.name });
}
return (
<form onSubmit={handleSubmit}>
<input value={name} onChange={(event) => setName(event.target.value)} />
<label>
<input type="checkbox" checked={accepted} onChange={(event) => setAccepted(event.target.checked)} />
接受学习计划
</label>
<input ref={fileRef} type="file" />
<button type="submit">提交</button>
</form>
);
}
type LessonNote = { title: string; done: boolean };\nconst note: LessonNote = { title: 'React 教程', done: false };
规则与陷阱
规则的价值在于让多人维护同一个项目时仍能预测行为。下面这些限制看似细碎,实际都在保护组件的输入、输出和生命周期边界。
- 受控输入必须同时提供 value 和 onChange。
- 表单提交要调用 event.preventDefault(),避免页面刷新。
- checkbox 使用 checked,不使用 value 表示选中状态。
- 文件上传适合非受控组件,因为浏览器限制脚本直接设置文件值。
练习
练习应当先小后大:先验证一个概念,再把它接入完整页面。不要在没有理解失败原因时复制更复杂的代码。
- 实现一个包含姓名和邮箱的受控表单。
- 增加 checkbox 并在提交时打印状态。
- 加入一个 ref 文件输入,说明它为什么是非受控组件。