HoRain云--React受控与非受控组件终极对比

  

🎬 HoRain云小助手个人主页

 🔥 个人专栏: 《Linux 系列教程》《c语言教程

⛺️生活的理想,就是为了理想的生活!


⛳️ 推荐

前些天发现了一个超棒的服务器购买网站,性价比超高,大内存超划算!忍不住分享一下给大家。点击跳转到网站。

专栏介绍

专栏名称

专栏介绍

《C语言》

本专栏主要撰写C干货内容和编程技巧,让大家从底层了解C,把更多的知识由抽象到简单通俗易懂。

《网络协议》

本专栏主要是注重从底层来给大家一步步剖析网络协议的奥秘,一起解密网络协议在运行中协议的基本运行机制!

《docker容器精解篇》

全面深入解析 docker 容器,从基础到进阶,涵盖原理、操作、实践案例,助您精通 docker。

《linux系列》

本专栏主要撰写Linux干货内容,从基础到进阶,知识由抽象到简单通俗易懂,帮你从新手小白到扫地僧。

《python 系列》

本专栏着重撰写Python相关的干货内容与编程技巧,助力大家从底层去认识Python,将更多复杂的知识由抽象转化为简单易懂的内容。

《试题库》

本专栏主要是发布一些考试和练习题库(涵盖软考、HCIE、HRCE、CCNA等)

目录

⛳️ 推荐

专栏介绍

🧠 一、受控组件(Controlled Components)

✅ 定义

💡 实现方式

✅ 优点

❌ 缺点

🎯 适用场景

🧠 二、非受控组件(Uncontrolled Components)

✅ 定义

💡 实现方式

✅ 优点

❌ 缺点

🎯 适用场景

📊 三、对比总结

🧩 四、何时选择哪种?

🔚 五、总结


img

在 React 中,受控组件(Controlled Components)非受控组件(Uncontrolled Components) 是处理表单数据的两种核心方式,它们反映了 React 数据流的设计哲学和实际开发中的灵活性需求。下面将从定义、实现方式、优缺点和适用场景等方面进行详细对比和分析。


🧠 一、受控组件(Controlled Components)

✅ 定义

受控组件是指其值(value)由 React 的状态(state) 控制,即表单的值完全由 React 管理。每当用户输入内容时,React 会通过 onChange 事件更新状态,从而实现双向绑定的效果。

💡 实现方式

import React, { useState } from 'react';

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

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

  return (
    <input
      type="text"
      value={value}
      onChange={handleChange}
    />
  );
}

✅ 优点

  • 数据一致性:React 的状态是数据的唯一来源,便于统一管理。
  • 表单验证:可以轻松在 onChange 或提交时添加验证逻辑。
  • 集成好:与 React 的其他特性(如表单提交、状态管理等)无缝集成。
  • 可测试性强:由于状态由 React 控制,更容易进行单元测试。

❌ 缺点

  • 代码冗余:需要为每个表单字段编写 onChange 事件处理逻辑。
  • 性能开销:频繁的状态更新可能导致不必要的渲染。

🎯 适用场景

  • 表单需要实时验证(如密码强度、邮箱格式等)
  • 表单字段之间有联动(如选择某个选项后显示其他字段)
  • 需要与 Redux、Context API 等状态管理工具集成

🧠 二、非受控组件(Uncontrolled Components)

✅ 定义

非受控组件是指其值由 DOM 本身管理,React 不主动控制其值。通常通过 ref 来访问表单元素的值,而不是通过 state 来同步。

💡 实现方式

import React, { useRef } from 'react';

function UncontrolledInput() {
  const inputRef = useRef(null);

  const handleSubmit = (e) => {
    e.preventDefault();
    console.log('输入内容:', inputRef.current.value);
  };

  return (
    <form onSubmit={handleSubmit}>
      <input type="text" ref={inputRef} />
      <button type="submit">提交</button>
    </form>
  );
}

✅ 优点

  • 实现简单:无需处理 onChange 事件,适合快速原型开发。
  • 性能更好:避免了频繁的 state 更新和渲染。

❌ 缺点

  • 数据不一致:表单值由 DOM 管理,React 无法实时跟踪其变化。
  • 难以验证:表单验证需要手动在提交时处理。
  • 与 React 其他特性集成差:不便于与表单库或状态管理工具结合使用。

🎯 适用场景

  • 表单字段较少且无需复杂验证
  • 需要直接访问 DOM(如文件上传)
  • 性能敏感的场景(如大型表单)

📊 三、对比总结

特性受控组件非受控组件
数据来源React 状态(state)DOM 本身
数据同步机制onChange 更新状态通过 ref 访问值
表单验证容易,可在 onChange 中处理需要在提交时处理
与 React 集成度
适合复杂表单
适合简单表单
适合文件上传✅(<input type="file" />
性能稍差(频繁更新)更好(无状态更新)

🧩 四、何时选择哪种?

场景推荐组件类型
复杂表单,需要实时验证和联动受控组件
快速原型开发或小型表单非受控组件
文件上传(React 无法控制其值)非受控组件
表单字段较多,需要统一管理受控组件
需要与 Redux、Formik 等库集成受控组件

🔚 五、总结

  • 受控组件 是 React 推荐的方式,尤其适合需要复杂交互和验证的表单场景。
  • 非受控组件 更加轻量,适合简单的表单或需要直接操作 DOM 的场景(如文件上传)。
  • 在实际开发中,可以根据项目需求灵活选择,甚至在同一表单中混合使用两者(例如,大部分字段用受控组件,文件输入用非受控组件)。

如果你正在开发一个复杂的表单系统,建议优先使用 受控组件,并结合像 Formik、React Hook Form 这样的表单库来简化开发流程。

❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄

💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍

🔥🔥🔥Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙

### React受控组件与非受控组件的区别及使用场景 #### 受控组件 (Controlled Components) 在 React 中,当表单元素的状态由 React 的状态管理时,这些组件被称为 **受控组件**。这意味着所有的表单数据都存储在 React 组件的状态中,并通过 `props` 或回调函数来更新。 - 表单元素的值始终由 React 状态控制。 - 需要显式地处理每次用户输入事件并更新状态。 - 更适合复杂的交互逻辑和动态验证场景。 以下是创建受控组件的一个简单例子: ```javascript class ControlledForm extends React.Component { constructor(props) { super(props); this.state = { value: '' }; } handleChange = (event) => { this.setState({ value: event.target.value }); }; handleSubmit = (event) => { alert('提交的内容: ' + this.state.value); event.preventDefault(); }; render() { return ( <form onSubmit={this.handleSubmit}> <label> 名字: <input type="text" value={this.state.value} onChange={this.handleChange} /> </label> <input type="submit" value="提交" /> </form> ); } } ``` 这种模式允许开发者完全掌控表单的行为及其状态变化[^4]。 --- #### 非受控组件 (Uncontrolled Components) 相比之下,**非受控组件**更接近于原生 HTML 的行为方式。在这种情况下,React 不会维护表单元素的状态,而是让 DOM 自己保存其当前值。 - 使用 `ref` 来获取 DOM 节点中的实际值。 - 对简单的表单或者不需要频繁更新的应用程序来说更为简洁高效。 下面是一个典型的非受控组件实现方法: ```javascript class UncontrolledForm extends React.Component { constructor(props) { super(props); this.inputRef = React.createRef(); // 创建 ref 实例 } handleSubmit = (event) => { alert('提交的内容: ' + this.inputRef.current.value); // 访问 input 值 event.preventDefault(); }; render() { return ( <form onSubmit={this.handleSubmit}> <label> 名字: <input type="text" ref={this.inputRef} /> {/* 将 ref 关联到 input */} </label> <input type="submit" value="提交" /> </form> ); } } ``` 这种方式更适合那些只需要读取最终结果而无需实时监听中间过程的情况[^4]。 --- #### 主要区别总结 | 特性 | 受控组件 | 非受控组件 | |--------------------------|-----------------------------------|----------------------------| | 数据源 | React State | DOM | | 更新机制 | 显式的 setState 和事件处理器 | 默认浏览器行为 | | 复杂度 | 较高 | 较低 | | 场景适用 | 动态验证、复杂业务逻辑 | 简单表单或静态页面 | --- #### 使用场景分析 1. 如果应用程序需要对用户的每一次输入做出反应(例如自动完成建议),则应优先考虑采用 **受控组件**。 2. 当仅需收集最终的结果而不关心具体的变化细节时,则可以选用更加轻量级的解决方案——即 **非受控组件**。 尽管如此,在现代开发实践中推荐更多地依赖于受控组件,因为它们能够更好地融入 React 的生态系统并与诸如 Redux 这样的全局状态管理系统集成[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值