React中的受控组件与非受控组件

585 阅读3分钟

引言 💭

在 React 中,表单组件有两种常见的处理方式:受控组件和非受控组件。

一、受控组件

定义
受控组件是指那些表单元素的值由 React 组件的状态(state)来控制。也就是说,组件的状态是唯一的数据源,表单的输入值通过状态来绑定和更新。

实现
在受控组件中,React 会将表单元素的值绑定到组件的状态上,所有输入变化通过事件处理函数(如 onChange)来更新状态。这使得开发者能够完全控制用户输入。

示例代码

import React, { useState } from 'react';

function ControlledForm() {
  const [value, setValue] = useState('');

  const handleChange = (event) => {
    setValue(event.target.value);
  };

  const handleSubmit = (event) => {
    event.preventDefault();
    alert('A name was submitted: ' + value);
  };

  return (
    <form onSubmit={handleSubmit}>
      <label>
        Name:
        <input type="text" value={value} onChange={handleChange} />
      </label>
      <button type="submit">Submit</button>
    </form>
  );
}

特点

  • 输入值由 state 管理,通过事件(如 onChange)更新状态。
  • 数据和 UI 是同步的,React 控制表单元素的值。
  • 易于实现表单验证、错误提示和与外部数据交互。

优点

  • 更易维护和调试,因为所有表单数据都由 React 状态管理。
  • 更强的控制力,可以通过生命周期方法进行额外操作。
  • 方便实现表单验证、数据格式化和其他业务逻辑。

缺点

  • 表单较复杂时可能会导致大量状态更新,从而影响性能。
  • 每次输入都会触发状态更新,可能导致多次渲染。

二、非受控组件

定义
非受控组件是指表单元素的值不由 React 状态管理,而是由 DOM 自身管理。在这种情况下,React 并不控制表单元素的值,用户输入直接存储在 DOM 中,开发者通过 ref 来访问和操作输入值。

实现
在非受控组件中,表单元素的值通过 ref 访问,不需要将值绑定到组件的状态。这种方式类似于传统的 HTML 表单处理方式。

示例代码

import React, { useRef } from 'react';

function UncontrolledForm() {
  const inputRef = useRef();

  const handleSubmit = (event) => {
    event.preventDefault();
    alert('A name was submitted: ' + inputRef.current.value);
  };

  return (
    <form onSubmit={handleSubmit}>
      <label>
        Name:
        <input type="text" ref={inputRef} />
      </label>
      <button type="submit">Submit</button>
    </form>
  );
}

特点

  • 使用 ref 直接访问 DOM 元素的值,React 不控制输入。
  • 用户输入直接更新 DOM,React 不参与状态管理。
  • ref 可以在需要时获取输入的当前值。

优点

  • 代码简洁,适用于表单不需要频繁更新的场景。
  • 避免了不必要的渲染,提高了性能。

缺点

  • 难以进行复杂的表单验证或处理,因为 React 不直接管理输入的状态。
  • 无法直接利用 React 的状态管理进行数据同步或交互。

三、受控组件与非受控组件的选择

  • 使用受控组件的场景

    • 当需要在用户输入时进行表单验证或动态更新 UI。
    • 需要通过状态控制表单提交或数据格式化。
    • 需要与外部状态或 React 生命周期方法进行交互。
  • 使用非受控组件的场景

    • 表单较为简单,不需要频繁更新或验证。
    • 想避免频繁的状态更新,以提升性能。
    • 在某些情况下,直接操作 DOM 比通过 React 更为灵活。

结语✒️

  • 受控组件:提供更强的灵活性和控制力,特别适合复杂的表单逻辑,如验证、错误处理和动态更新。
  • 非受控组件:简洁高效,适用于那些不需要频繁交互或状态同步的简单表单。

一般来说,对于大多数需要高度交互和验证的表单,受控组件是首选。但在简单的表单或对性能要求较高的情况下,非受控组件也可以提供优势。

猫抓爱心 (2).gif