React受控组件的核心原理与实战精要

在 React 中,受控组件(Controlled Component) 是一种重要的模式,用于通过组件的状态来管理表单元素的值。这种模式不仅确保了数据的一致性和可预测性,还便于与其他功能(如验证和格式化)集成。本文将深入探讨受控组件的核心原理、实战应用及其优缺点。


1. 何为受控组件
定义

在 React 中,受控组件是指那些其值由 React 状态管理的表单元素。与传统的 HTML 表单元素不同,React 的受控组件不会自行维护状态,而是通过 React 组件的状态(state)来控制输入值,并在每次用户交互时更新状态。

核心特点
  • 表单元素的值由 React 状态控制:表单元素的 value 属性绑定到组件的状态。
  • 事件处理函数更新状态:每当用户进行输入时,触发事件处理函数(如 onChange),该函数会更新组件的状态,从而重新渲染表单元素。

2. 传统 HTML 表单元素的行为

在普通的 HTML 中,表单元素(如 <input>, <textarea>, 和 <select>)会自行维护其内部状态。例如:

<input type="text" value="initial value" />

在这种情况下,输入框会显示初始值,但用户的任何输入都会直接修改输入框的内容,而这些变化不会自动反映到应用的其他部分。


3. React 中的受控组件

以下是一个简单的例子,展示了如何创建一个受控组件:

import React, { useState } from 'react';function MyForm() {// 使用 useState 钩子初始化状态const [inputValue, setInputValue] = useState('');// 处理输入变化的回调函数const handleChange = (event) => {setInputValue(event.target.value);};// 处理表单提交的回调函数const handleSubmit = (event) => {event.preventDefault(); // 阻止默认的表单提交行为console.log('提交的值:', inputValue);};return (<form onSubmit={handleSubmit}>{/* 受控输入框 */}<input type="text" value={inputValue} onChange={handleChange} placeholder="请输入内容" /><button type="submit">提交</button></form>);
}export default MyForm;

在这个示例中:

  • 输入框的 value 属性被绑定到组件的状态 inputValue
  • 每次用户输入时,handleChange 函数会被调用,并更新 inputValue 状态。
  • 提交表单时,handleSubmit 函数会被调用,并输出当前的 inputValue
其他表单元素的使用

除了 <input>,React 还支持其他类型的表单元素,如 <textarea><select>

<textarea> 示例
const [textAreaValue, setTextAreaValue] = useState('');const handleTextAreaChange = (event) => {setTextAreaValue(event.target.value);
};return (<textarea value={textAreaValue} onChange={handleTextAreaChange}placeholder="请输入多行文本"/>
);
<select> 示例
const [selectedOption, setSelectedOption] = useState('apple');const handleSelectChange = (event) => {setSelectedOption(event.target.value);
};return (<select value={selectedOption} onChange={handleSelectChange}><option value="apple">苹果</option><option value="banana">香蕉</option><option value="orange">橙子</option></select>
);

4. 受控组件的优点
单一数据源

所有的数据都存储在组件的状态中,避免了数据分散和不一致的问题。这使得调试和维护变得更加容易。

易于集成和扩展

可以轻松地将表单数据与其他 React 功能(如验证、格式化等)集成。例如,可以在 handleChange 函数中添加验证逻辑:

const handleChange = (event) => {const newValue = event.target.value;if (newValue.length <= 10) {setInputValue(newValue);} else {console.error('输入长度不能超过10个字符');}
};
实时反馈

由于每次输入都会触发状态更新并重新渲染,因此可以立即看到输入结果的变化。这对于提供即时反馈(如实时搜索或格式化输入)非常有用。

简化逻辑

不需要手动管理表单元素的状态,所有状态都在 React 组件中统一管理。这减少了潜在的错误和复杂性。


5. 受控组件的缺点

尽管受控组件有很多优点,但也有一些潜在的缺点:

性能开销

每次用户输入都会触发状态更新和重新渲染,这可能会对性能产生影响,尤其是在处理大量输入或复杂表单时。为了优化性能,可以使用 useCallbackshouldComponentUpdate 来减少不必要的渲染。

代码复杂性

需要编写更多的代码来管理状态和事件处理,尤其是对于复杂的表单结构。不过,随着对 React 状态管理机制的熟悉,这种复杂性会逐渐降低。


6. 与非受控组件的对比

除了受控组件外,React 还支持 非受控组件(Uncontrolled Component)。非受控组件允许表单元素自行维护其内部状态,而不是通过 React 状态来控制。

非受控组件示例
import React, { useRef } from 'react';function MyForm() {const inputRef = useRef(null);const handleSubmit = (event) => {event.preventDefault();console.log('提交的值:', inputRef.current.value);};return (<form onSubmit={handleSubmit}>{/* 非受控输入框 */}<input type="text" ref={inputRef}placeholder="请输入内容" /><button type="submit">提交</button></form>);
}export default MyForm;

在这个示例中:

  • 使用 ref 引用输入框元素,而不是通过状态来控制其值。
  • 在提交表单时,通过 inputRef.current.value 获取输入框的值。

虽然非受控组件在某些场景下更简单,但它们缺乏受控组件的一些优势,比如实时数据同步和易于集成。


7. 结合使用 useRef 和受控组件

有时你可能希望结合使用 useRef 和受控组件,以便在某些情况下访问 DOM 元素。例如:

import React, { useState, useRef } from 'react';function MyForm() {const [inputValue, setInputValue] = useState('');const inputRef = useRef(null);const handleChange = (event) => {setInputValue(event.target.value);};const handleSubmit = (event) => {event.preventDefault();console.log('提交的值:', inputValue);console.log('DOM 元素的值:', inputRef.current.value); // 访问 DOM 元素的值};return (<form onSubmit={handleSubmit}><input type="text" value={inputValue} onChange={handleChange} ref={inputRef}placeholder="请输入内容" /><button type="submit">提交</button></form>);
}export default MyForm;

在这个示例中,我们既使用了状态来控制输入框的值,又使用了 ref 来访问 DOM 元素的值。这种组合方式在某些特定场景下非常有用,例如需要访问 DOM 属性或执行 DOM 操作时。


总结

  • 受控组件 是 React 中一种重要的模式,用于通过组件状态来控制表单元素的值。
  • 它们确保数据的一致性和可预测性,并且便于集成其他功能,如验证和格式化。
  • 尽管受控组件在某些情况下可能会带来性能开销,但它们提供了更好的开发体验和更高的灵活性。
  • 对于简单的表单需求,可以考虑使用 非受控组件,但在大多数情况下,推荐使用受控组件以获得更好的数据管理和用户体验。

通过理解和应用这些受控组件的核心原理和最佳实践,你可以构建出更加健壮和高效的 React 应用程序。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/15372.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第433场周赛:变长子数组求和、最多 K 个元素的子序列的最值之和、粉刷房子 Ⅳ、最多 K 个元素的子数组的最值之和

Q1、变长子数组求和 1、题目描述 给你一个长度为 n 的整数数组 nums 。对于 每个 下标 i&#xff08;0 < i < n&#xff09;&#xff0c;定义对应的子数组 nums[start ... i]&#xff08;start max(0, i - nums[i])&#xff09;。 返回为数组中每个下标定义的子数组中…

CSS 伪类(Pseudo-classes)的详细介绍

CSS 伪类详解与示例 在日常的前端开发中&#xff0c;CSS 伪类可以帮助我们非常精准地选择元素或其特定状态&#xff0c;从而达到丰富页面表现的目的。本文将详细介绍以下伪类的使用&#xff1a; 表单相关伪类 :checked、:disabled、:enabled、:in-range、:invalid、:optional、…

Centos挂载镜像制作本地yum源,并补装图形界面

内网环境centos7.9安装图形页面内网环境制作本地yum源 上传镜像到服务器目录 创建目录并挂载镜像 #创建目录 cd /mnt/ mkdir iso#挂载 mount -o loop ./CentOS-7-x86_64-DVD-2009.iso ./iso #前面镜像所在目录&#xff0c;后面所挂载得目录#检查 [rootlocalhost mnt]# df -h…

大模型推理——MLA实现方案

1.整体流程 先上一张图来整体理解下MLA的计算过程 2.实现代码 import math import torch import torch.nn as nn# rms归一化 class RMSNorm(nn.Module):""""""def __init__(self, hidden_size, eps1e-6):super().__init__()self.weight nn.Pa…

Python截图轻量化工具

一、兼容局限性 这是用Python做的截图工具&#xff0c;不过由于使用了ctypes调用了Windows的API, 同时访问了Windows中"C:/Windows/Cursors/"中的.cur光标样式文件, 这个工具只适用于Windows环境&#xff1b; 如果要提升其跨平台性的话&#xff0c;需要考虑替换cty…

链表(LinkedList) 1

上期内容我们讲述了顺序表&#xff0c;知道了顺序表的底层是一段连续的空间进行存储(数组)&#xff0c;在插入元素或者删除元素需要将顺序表中的元素整体移动&#xff0c;时间复杂度是O(n)&#xff0c;效率比较低。因此&#xff0c;在Java的集合结构中又引入了链表来解决这一问…

SpringAI系列 - 使用LangGPT编写高质量的Prompt

目录 一、LangGPT —— 人人都可编写高质量 Prompt二、快速上手2.1 诗人 三、Role 模板3.1 Role 模板3.2 Role 模板使用步骤3.3 更多例子 四、高级用法4.1 变量4.2 命令4.3 Reminder4.4 条件语句4.5 Json or Yaml 方便程序开发 一、LangGPT —— 人人都可编写高质量 Prompt La…

jupyterLab插件开发

jupyter lab安装、配置&#xff1a; jupyter lab安装、配置教程_容器里装jupyterlab-CSDN博客 『Linux笔记』服务器搭建神器JupyterLab_linux_布衣小张-腾讯云开发者社区 Jupyter Lab | 安装、配置、插件推荐、多用户使用教程-腾讯云开发者社区-腾讯云 jupyterLab插件开发教…

使用LLaMA Factory踩坑记录

前置条件&#xff1a;电脑显卡RTX 4080 问题&#xff1a;LLaMA-Factory在运行的时候&#xff0c;弹出未检测到CUDA的报错信息 结论&#xff1a;出现了以上的报错&#xff0c;主要可以归结于以下两个方面&#xff1a; 1、没有安装GPU版本的pytorch&#xff0c;下载的是CPU版本…

『Apisix进阶篇』结合Consul作服务发现实战演练

文章目录 一、引言二、APISIX与Consul集成2.1 环境准备2.2 配置Consul服务发现2.2.1 修改APISIX配置文件2.2.2 重启APISIX 2.3 在路由中使用Consul服务发现2.3.1 创建路由2.3.2 验证路由 2.4 高级配置2.4.1 服务过滤2.4.2 多数据中心支持 三、总结 &#x1f4e3;读完这篇文章里…

SpringBoot速成(八)登录实战:未登录不能访问 P5-P8

1.登录 package com.itheima.springbootconfigfile.controller;import com.itheima.springbootconfigfile.pojo.Result; import com.itheima.springbootconfigfile.pojo.User; import com.itheima.springbootconfigfile.service.UserService;import com.itheima.springbootco…

对接DeepSeek

其实&#xff0c;整个对接过程很简单&#xff0c;就四步&#xff0c;获取key&#xff0c;找到接口文档&#xff0c;接口测试&#xff0c;代码对接。 获取 KEY https://platform.deepseek.com/transactions 直接付款就是了&#xff08;现在官网暂停充值2025年2月7日&#xff0…

ASP.NET Core JWT

目录 Session的缺点 JWT&#xff08;Json Web Token&#xff09; 优点&#xff1a; 登录流程 JWT的基本使用 生成JWT 解码JWT 用JwtSecurityTokenHandler对JWT解码 注意 Session的缺点 对于分布式集群环境&#xff0c;Session数据保存在服务器内存中就不合适了&#…

【MySQL】深度学习数据库开发技术:使用CC++语言访问数据库

**前言&#xff1a;**本节内容介绍使用C/C访问数据库&#xff0c; 包括对数据库的增删查改操作。 主要是学习一些接口的调用&#xff0c; 废话不多说&#xff0c; 开始我们的学习吧&#xff01; ps:本节内容比较容易&#xff0c; 友友们放心观看哦&#xff01; 目录 准备mysql…

postgreSQL16.6源码安装

1.获取源码 从PostgreSQL: File Browser获取tar.bz2或者tar.gz源码 2.解压 tar xf postgresql-version.tar.bz2 roothwz-VMware-Virtual-Platform:/usr/local# tar xf postgresql-16.6.tar.bz2 roothwz-VMware-Virtual-Platform:/usr/local# ll 总计 24324 drwxr-xr-x 12 ro…

音频进阶学习十一——离散傅里叶级数DFS

文章目录 前言一、傅里叶级数1.定义2.周期信号序列3.表达式DFSIDFS参数含义 4.DFS公式解析1&#xff09;右边解析 T T T、 f f f、 ω \omega ω的关系求和公式N的释义求和公式K的释义 e j ( − 2 π k n N ) e^{j(\frac{-2\pi kn}{N})} ej(N−2πkn​)的释义 ∑ n 0 N − 1 e…

【kafka系列】Topic 与 Partition

Kafka 的 Topic&#xff08;主题&#xff09; 和 Partition&#xff08;分区&#xff09; 是数据组织的核心概念&#xff0c;它们的映射关系及在 Broker 上的分布直接影响 Kafka 的性能、扩展性和容错能力。以下是详细解析&#xff1a; 一、Topic 与 Partition 的映射关系 Top…

卷积神经网络CNN如何处理语音信号

卷积神经网络&#xff08;CNN&#xff09;在处理语音数据时通常不直接处理原始的一维波形信号&#xff0c;而是处理经过预处理的二维语音特征图。以下是CNN处理语音数据时的常见数据类型和步骤&#xff1a; 1. 语音信号预处理 语音信号通常是一维的时间序列&#xff08;波形信…

【MQ】Spring3 中 RabbitMQ 的使用与常见场景

一、初识 MQ 传统的单体架构&#xff0c;分布式架构的同步调用里&#xff0c;无论是方法调用&#xff0c;还是 OpenFeign 难免会有以下问题&#xff1a; 扩展性差&#xff08;高耦合&#xff0c;需要依赖对应的服务&#xff0c;同样的事件&#xff0c;不断有新需求&#xff0…

GB/T 43698-2024 《网络安全技术 软件供应链安全要求》标准解读

一、43698-2024标准图解 https://mmbiz.qpic.cn/sz_mmbiz_png/rwcfRwCticvgeBPR8TWIPywUP8nGp4IMFwwrxAHMZ9Enfp3wibNxnfichT5zs7rh2FxTZWMxz0je9TZSqQ0lNZ7lQ/640?wx_fmtpng&fromappmsg 标准在线预览&#xff1a; 国家标准|GB/T 43698-2024 相关标准&#xff1a; &a…