非受控 vs 受控 React 组件
发布: (2026年2月4日 GMT+8 11:50)
3 min read
原文: Dev.to
Source: Dev.to
React 为开发者提供了多种管理和处理应用中组件的方法。两种常见的做法是 uncontrolled(非受控)和 controlled(受控)组件。虽然两者都用于管理用户输入和交互,但在实现方式和使用场景上有显著差异。
Uncontrolled Components
非受控组件依赖 DOM 来保存其状态。React 并不直接控制这些值,而是在需要时读取它们(例如表单提交时)。
Advantages
- DOM‑driven:表单数据由 DOM 本身管理。
- Integration with non‑React code:更容易与外部库或遗留代码配合使用,因为真相来源仍然是 DOM。
- Simplified implementation:所需的状态处理器更少,对于大型表单来说非常方便。
- Potential performance benefit:React 不会介入每一次输入变化,从而减少重新渲染的开销。
Disadvantages
- Limited control:更难强制执行验证规则或与其他 React 特性(如 Context、PropTypes)同步。
- Testing challenges:由于状态存在于 DOM 中,模拟交互并断言结果会更复杂。
Example
import React, { useRef } from "react";
function UncontrolledForm() {
const inputRef = useRef(null);
function handleSubmit(event) {
event.preventDefault();
console.log("Submitted value:", inputRef.current.value);
}
return (
Name:
Submit
);
}
export default UncontrolledForm;
在此示例中,输入的值由 DOM(defaultValue)管理。React 仅在表单提交时读取当前值。
Controlled Components
受控组件将状态保存在 React 内部。组件的渲染输出始终反映当前状态,用户交互通过事件处理器更新该状态。
Advantages
- Full control:React 可以强制执行验证、与其他功能集成,并保证行为可预测。
- Improved testing:状态是显式的,模拟变化和断言结果变得直观。
- Centralized state management:所有表单数据都存放在 React 状态中,便于共享和操作。
- Clear event handling:
onChange(或类似)处理器保持 UI 与状态同步。
Disadvantages
- Increased complexity:每个输入都需要显式的状态处理,对于大型表单可能会变得冗长。
- Potential performance overhead:频繁的状态更新会触发重新渲染,在非常大或高度交互的表单中可能影响性能。
Example
import React, { useState } from "react";
function ControlledForm() {
const [name, setName] = useState("John Doe");
function handleChange(event) {
setName(event.target.value);
}
function handleSubmit(event) {
event.preventDefault();
console.log("Submitted value:", name);
}
return (
Name:
Submit
);
}
export default ControlledForm;
这里,输入的 value 绑定到 React 状态(name)。onChange 处理器更新该状态,确保 UI 始终显示当前值。