非受控 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 handlingonChange(或类似)处理器保持 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 始终显示当前值。

Back to Blog

相关文章

阅读更多 »