受控组件与非受控组件
React 中的受控组件和非受控组件都是指的表单组件,其区别主要是表单值是由 React 处理还是由浏览器处理。
受控组件
表单元素,如input
、textarea
、select
等,通常都是自行维护 State 并根据用户的输入进行更新。通过与 React 组件中的 State 进行组合,可以使 React 组件中的 State 成为唯一数据源。渲染表单的 React 组件在控制组件 State 的同时,还控制用户输入过程中的表单操作,还可以更方便的对用户输入的内容进行验证,这就形成了受控组件。
所以在项目中,一般可以通过以下方式来获取用户的输入。
function UserForm(props) {
const [formState, setFormState] = useState({
username: "",
password: "",
});
const handleChange = (event) => {
event.preventDefault();
setFormState({ ...formState, [event.target.name]: event.target.value });
};
return (
<form onSubmit={handleSubmit}>
<label>
用户名:
<input
type="text"
name="username"
value={formState.username}
onChange={handleChange}
/>
</label>
<label>
密码:
<input
type="password"
name="password"
value={formState.password}
onChange={handleChange}
/>
</label>
</form>
);
}
非受控组件
受控组件的 State 数据都保存在 React 组件的 State 中,这就需要在 React 组件中编写大量用于控制 DOM 节点的逻辑。虽然在大部分情况下推荐使用受控组件来处理表单数据,但是在表单规模很大或者使用文件上传时,可以使用非受控组件来替代处理。
非受控组件可以使用ref
来从 DOM 节点中获取表单数据。以下是上例的替代示例。
function UserForm() {
const user = useRef();
const pass = useRef();
const handleSubmit = (event) => {
const formData = {
user: user.current.value,
pass: pass.current.value,
};
event.preventDefault();
};
return (
<form onSubmit={handleSubmit}>
<label>
用户名:
<input type="text" ref={user} />
</label>
<label>
密码:
<input type="password" ref={pass} />
</label>
</form>
);
}
在使用ref
来获取非受控组件的值时,通常需要给定组件一个初始值,这个初始值可以在组件上通过属性defaultValue
和defaultChecked
来赋予。