什么是受控组件与非受控组件?

描述 React 中受控组件和非受控组件的区别,包括它们的定义、特点及适用场景。

React 中等 受控组件 非受控组件 Component

在 React 中,受控组件(Controlled Components)和非受控组件(Uncontrolled Components)是处理表单元素或用户输入的两种不同方式,核心区别在于数据管理的责任由 React 还是 DOM 本身承担。以下是详细介绍:

1. 受控组件(Controlled Components)

  • 定义:受控组件的表单值完全由 React 组件状态管理。用户输入触发事件处理函数,更新 state,并通过重新渲染来同步 DOM 的值。所有数据流动由 React 控制,实现双向绑定。
  • 关键特征
    • 值由 stateprops 直接控制(如将值绑定到输入框的 value 属性)。
    • 通过 onChange 等事件处理器更新状态。
    • 易于实现表单验证、数据清洗和实时处理.
  • 代码示例
     import React, { useState } from 'react';
    
     function ControlledInput() {
       const [inputValue, setInputValue] = useState('');
    
       const handleChange = (e) => {
         setInputValue(e.target.value);
       };
    
       return <input type="text" value={inputValue} onChange={handleChange} />;
     }
    

2. 非受控组件(Uncontrolled Components)

  • 定义:非受控组件的值由 DOM 自身管理,而非 React state。值直接由用户输入设定,React 组件通常通过 ref 来读取当前值,但不能直接更新它,依赖于原生 HTML 行为.
  • 关键特征
    • 值由 DOM 引用获取(使用 ref API),而不是绑定的 state。
    • 数据流动是单向的,从用户输入到读取值。
    • 代码更简洁,适用于不需要复杂状态交互的场景.
  • 代码示例
     import React, { useRef } from 'react';
    
     function UncontrolledInput() {
       const inputRef = useRef();
    
       const handleSubmit = () => {
         alert(inputRef.current.value);
       };
    
       return (
         <div>
           <input type="text" ref={inputRef} />
           <button onClick={handleSubmit}>Submit</button>
         </div>
       );
     }
    

3. 受控与非受控组件的主要区别

  • 数据管理方式
    • 受控组件:数据流双向(state 绑定到 DOM,用户输入更新 state),React 负责同步.
    • 非受控组件:数据流单向(依赖 ref 读取值),React 不干预状态变化.
  • 控制力
    • 受控组件提供精准控制,适用于表单验证、动态 UI 或要求实时状态更新的场景(如搜索框过滤)。
    • 非受控组件简化处理,适用于文件上传、输入范围控件或与第三方库集成,避免 React 过多状态干预.
  • 性能与复杂度
    • 受控组件更重但可控性强,频繁状态更新可能导致较多 re-render;非受控组件更轻量,因 DOM 直接驱动,少 re-render.

4. 适用场景

  • 使用受控组件
    • 场景:表单字段验证、动态更新其他组件状态、多步表单处理或需要访问 React 生命周期。
    • 例如:在线编辑器或条件验证表单中,状态驱动提供统一管理.
  • 使用非受控组件
    • 场景:简单表单提交、大文件输入按钮、快速原型开发或追求性能优化的环境.
    • 例如:集成 jquery 等原生库时减少侵入性操作或优化减少 re-render 开销.

总的来说,在 React 应用中,选择受控组件利于控制和扩展;非受控组件适合简化开发流程。根据项目需求偏好切换处理方式。