表单处理是构建现代 Web 应用程序最重要的部分之一。无论是登录页面、注册表单还是结账页面,表单都是用户与应用程序交互的主要方式。
👉 受控组件
👉 非受控组件
乍一看,这两种方法可能看起来很相似——它们都渲染输入并捕获数据。但实际上,它们在管理值、验证
和响应性方面存在显著差异。
选择正确的方法会影响性能
、代码复杂性和可维护性。
1. 简介:为什么表单在 React 中很重要
表单是 Web 应用程序中用户交互的支柱:
- 用户通过表格登录
- 他们使用表格进行注册
- 他们订购产品、留下评论或发送反馈——全部通过表格进行
在纯 HTML/JavaScript 中,浏览器会在内部处理表单数据。但 React 不同——它需要决定数据如何流动:
- React 是否应该通过
React状态
完全控制输入值?(受控组件
) - 或者浏览器
DOM
应该管理值,而 React 只在必要时读取它们?(非受控组件
)
2. 什么是受控组件
?
受控组件
是一个表单元素,其值完全由React状态
管理。
React 的 useState
(或其他状态工具)充当唯一事实来源,而不是输入存储其自己的数据。
每次击键都会更新状态,并且输入会使用新值重新呈现。
✅ 示例:受控组件
import React, { useState } from "react";
function ControlledForm() {
const [email, setEmail] = useState("");
const handleSubmit = (e) => {
e.preventDefault();
alert(`Submitted Email: ${email}`);
};
return (
<form onSubmit={handleSubmit}>
<label>Email: </label>
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
<button type="submit">Submit</button>
</form>
);
}
🔄 工作原理(图表)
User Input → onChange → React State (setEmail) → Re-render → Input value updated
在这里,React 始终控制着输入值。
👍 受控组件
的优点
- ✅ 可预测:数据存在于
React状态
中,使调试更容易 - ✅
验证
:非常适合实时验证
(例如,如果电子邮件无效则显示错误) - ✅ 动态 UI:用于启用/禁用按钮或显示条件元素
- ✅ 单一事实来源:所有输入值都存储在一个地方(状态)
👎 受控组件
的缺点
- ❌ 更多样板:每个字段都需要值和 onChange
- ❌
性能
开销:每次击键都会触发重新渲染
3. 什么是非受控组件
?
非受控组件
是浏览器DOM
管理输入值的表单元素。
我们不使用 React 保存状态,而是使用 useRef
来访问值。
✅ 示例:非受控组件
import React, { useRef } from "react";
function UncontrolledForm() {
const emailRef = useRef();
const handleSubmit = (e) => {
e.preventDefault();
alert(`Submitted Email: ${emailRef.current.value}`);
};
return (
<form onSubmit={handleSubmit}>
<label>Email: </label>
<input type="email" ref={emailRef} />
<button type="submit">Submit</button>
</form>
);
}
🔄 工作原理(图表)
User Input → DOM stores value → React reads value via ref when needed
在这里,React 不控制值——DOM
控制。
👍 非受控组件
的优点
- ✅ 更少的代码:不需要
useState
或 onChange - ✅
性能
:由于 React 不会在每次击键时更新,因此重新渲染次数更少 - ✅ 简单:非常适合不需要
验证
的快速表单
👎 非受控组件
的缺点
- ❌ 有限的
验证
:很难即时验证
输入 - ❌ 不太可预测:React 并不总是知道当前值
- ❌ 不可扩展:难以用于复杂的表单
4. 受控组件
与非受控组件
——并列对比
我们不用表格,而是用简单的文字来比较:
数据处理
受控组件
→ 由React状态
管理非受控组件
→ 由DOM
管理
最适合
受控组件
→ 动态表单、验证
、条件渲染非受控组件
→ 简单表单、快速输入、性能
关键型应用
优点
受控组件
→ 可预测、可测试、灵活非受控组件
→ 更简单、代码更少、更少重新渲染
缺点
受控组件
→ 更多的样板代码,需要更多更新非受控组件
→ 控制力较弱,验证
棘手
5. 高级用例
混合表单(混合受控组件
和非受控组件
)
某些字段(例如密码或电子邮件)需要验证
– 使用受控组件
。
其他字段(例如评论或可选注释)可以使用非受控组件
,以减少开销。
这种平衡有助于提高性能
和可维护性。
性能
考虑
- 小形式 →
受控组件
工作正常 - 具有数百个字段的大型表单 →
非受控组件
(或库)可能表现更好
许多现代库(如 React Hook Form)在内部使用非受控组件
来提高性能
。
处理大型/复杂表单
无需手动编写逻辑,而是使用库:
- Formik →
受控组件
,state 驱动 - React Hook Form →
非受控组件
,ref 驱动
它们提供内置验证
、错误处理和可扩展性。
6. React Forms 的最佳实践
- ✅ 使用
受控组件
进行验证
、条件 UI 和动态更新 - ✅ 使用
非受控组件
来实现简单、快速、一次性的表单 - ✅ 对于生产规模的应用程序,请使用 Formik 或 React Hook Form 等库
- ✅ 将用户体验放在首位——流畅、响应迅速的表单比内部方法更重要
7. 结论:您应该选择哪一个?
两种方法都有其适用之处:
受控组件
→ 更多控制,更多代码非受控组件
→ 更简单,灵活性较差
对于大多数应用来说,受控组件
是更安全的默认选择。但是,当性能
或简洁性更重要时,请毫不犹豫地使用非受控组件
。
总结
React 为开发者提供了表单处理的灵活性。关键在于知道何时完全掌控(例如,需要大量验证
的表单),何时让DOM
处理(例如,简单的输入)。
👉 在您的 React 项目中您更喜欢哪种:受控组件
还是非受控组件
?
评论0