React组件简介

组件

在 React 中,组件(Component) 是 UI 的基本构建块。可以把它理解为一个独立的、可复用的 UI 单元,类似于函数,它接受输入(props),然后返回 React 元素来描述 UI。

组件的简单使用

在 React 中,组件主要分为两种:类组件和函数组件。但是在 React 18+ 之后,以不推荐使用类组件,而是推荐使用函数组件。

函数组件本质上是一个 Javascript 函数,然后返回一个 JSX 结构。函数组件的名字必须以大写字母开头,否则 React 会将其视为一个 HTML 标签。

函数组件更简单,它没有 this, 编写和阅读更简单,而状态则是通过 React Hooks 来实现的。下面是一个简单的函数组件的例子:

//  定义组件
function Button() {// 组件内部的逻辑return (<button>Click me</button>);
}

这样我们就创建了一个 React 组件,接下来,我们可以在 App 组件中使用它:

function App() {return (<div><Button /></div>)
}

除了 Button 组件,App 组件本身也是组件,也就是说组件可以嵌套使用。

组件的特点

  1. 组件必须返回一个 JSX 结构(或 null)
  2. 组件名称必须大写(如 MyComponent,不能写 myComponent)
  3. 可以组合嵌套(组件可以包含其他组件)
  4. 可以接收 props(用于传递数据)

组件的状态

在 React 组件中,状态(State) 是指组件内部可变的数据,用于控制组件的行为和 UI 的变化。当 state 发生变化 时,React 会自动重新渲染组件,更新 UI。

为什么需要状态?

有些数据不会变,比如 props 传递过来的值,但有些数据是会随用户交互变化的,比如:

  • 计数器的数值
  • 按钮的开关状态
  • 输入框中的内容

这些会变化的数据 就应该存到组件的 state 中。例如:

import { useState } from "react";function Counter() {// useState(0) 表示 count 初始值为 0const [count, setCount] = useState(0);return (<div><p>当前计数:{count}</p>{/* 点击按钮时,修改 count 值 */}<button onClick={() => setCount(count + 1)}>+1</button></div>);
}export default Counter;

当点击 +1 按钮时,会调用 setCount 方法,将 count 的值加 1,然后 React 会重新渲染组件,更新 UI。具体来说当组件的 state 发生变化时,React 执行以下流程:

  1. 调用 setState 或 useState 进行状态更新
  2. React 触发组件的重新渲染(函数组件会重新执行,类组件会触发 render 方法
  3. 生成新的 Virtual DOM(虚拟 DOM)
  4. 比较新的 Virtual DOM 和旧的 Virtual DOM(Diffing 算法)
  5. 计算差异后更新真实 DOM(Reconciliation 过程)

React 通过 useState(或 setState)触发状态更新,然后采用 调度机制(Scheduler)+ 批量更新(Batching) 来通知浏览器进行重新渲染。这种机制类似于 Qt 的信号槽或者是发布-订阅模式。但是 React 的更新机制与 Qt 的信号槽不同的是,React 的更新机制是异步的,而 Qt 的信号槽是同步的。

Virtual DOM 机制

React 并不会直接操作 真实 DOM(Real DOM),而是使用 Virtual DOM 来提升性能。

虚拟 DOM(Virtual DOM) 是 React 在内存中的 JavaScript 对象,它描述了 UI 结构。

每次 state 变化时,React 会重新创建一个新的 Virtual DOM。

Diffing 算法(Diff 算法)

React 通过 Diffing 算法 比较「新的 Virtual DOM」和「旧的 Virtual DOM」,找出不同点,只更新发生变化的部分,避免整个页面的重新渲染。

Diff 算法流程

  1. 树形对比

     如果新的 Virtual DOM 和旧的 Virtual DOM 不是相同的组件,则直接销毁旧组件,创建新组件。如果它们是同一个组件,则继续向下比较子元素。
    
  2. 属性对比(Props Diffing)

     如果 props 发生变化,则更新对应的 DOM 属性。
    
  3. 子元素对比(Children Diffing)

     使用Key 机制优化列表渲染(key 帮助 React 识别哪些元素是新增、删除或移动的,我们在列表渲染中接触过 key 机制)。
    

Reconciliation(协调过程)

React 在 Diffing 之后,使用 Reconciliation(协调过程) 将「最小的变更」应用到真实 DOM:

  • 仅修改需要更新的 DOM 节点
  • 不会重新创建整个 DOM 结构
  • 性能更高,避免不必要的操作

React 如何知道状态发生了变化?

当我们调用 setState(类组件)或 useState(函数组件)时,React 内部执行以下操作:

  1. 记录状态变更

    React 维护着一个 state 和 nextState。

    当调用 setState(newState) 时,React 不会立即修改 state,而是先把 newState 放入更新队列。

  2. 触发调度(Scheduler 机制)

    React 不是立刻重新渲染,而是将更新任务提交给 Scheduler(调度器),并进行批处理优化。

  3. 标记 Fiber 节点为「需要更新」

    React 使用 Fiber 架构,每个组件对应一个 Fiber 节点,setState 会让 Fiber 节点进入「更新状态」,等待下一次渲染。

为什么 React 不是立即更新?

React 采用 批量更新(Batching) 机制:

  • 同一个事件循环内的多个 setState 只会触发一次渲染,减少不必要的更新,提高性能。
  • React 18 引入 Concurrent Mode,可以延迟低优先级的更新,提高流畅度。

useState 修改状态

我们还是以一个简单的 Demo 为例,展示如何使用 useState 修改状态:

import { useState } from "react";   // 引入 useState
function Counter() {const [count, setCount] = useState(0);   // 初始化 count 为 0return (<div><p>当前计数:{count}</p><button onClick={() => setCount(count + 1)}>+1</button><button onClick={() => setCount(count - 1)}>-1</button></div>)
}

const [count, setCount] = useState(0); 这行代码就类似于发布订阅模式中,订阅者注册自己所需要关注的事件或消息。这里可以理解为订阅者注册了 count 变化时,会收到通知,然后更新 count 的值。

在 React 中,useState 是一个 Hook,用于在函数组件中添加状态。它返回一个数组,数组的第一个元素是当前状态的值,第二个元素是一个函数,用于更新状态。

直接改变 count 的值,并不会触发组件的重新渲染,因为 React 是通过 setState 来触发组件的重新渲染的。因此需要调用 setCount 来更新 count 的值,然后 React 会重新渲染组件,更新 UI。

多个状态值管理

你可以在 useState 中存储多个值,例如:

function UserInfo() {const [user, setUser] = useState({ name: "Alice", age: 25 });return (<div><p>姓名:{user.name}</p><p>年龄:{user.age}</p><button onClick={() => setUser({ ...user, age: user.age + 1 })}>生日+1</button></div>);
}

这里使用了 …user(展开运算符)来避免覆盖 name,仅修改 age。

组件样式控制

在 React 中,控制组件的样式,可以直接在行内样式中设置,也可以使用 className 属性来设置类名,然后在 CSS 文件中定义样式。在工程化中,一般是使用 className 来控制样式。

行内样式

在 React 中,你可以在行内样式中设置样式,例如:

<div style={{ color: 'red', fontSize: '16px' }}>Hello World</div>

在上面的例子中,style 属性是一个对象,其中包含了 CSS 属性及其值。你可以使用驼峰命名法来设置 CSS 属性,例如 color 和 fontSize。如果觉得 style 属性太长,可以定义一个变量来存储样式对象,然后使用变量来设置样式。例如:

const style = {color: 'red',fontSize: '16px'
}
<div style={style}>Hello World</div>

通过 className 来控制样式

在 React 中,你可以使用 className 属性来控制组件的样式,例如:

在 CSS 文件中,你可以定义一个类名为 my-class 的样式,例如:

.my-class {color: red;font-size: 16px;
}

在组件中,你可以使用 className 属性来设置类名,例如:

import './App.css';
<div className="my-class">Hello World</div>

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

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

相关文章

Kafka消息序列化深度革命:构建高性能、高安全的自定义编码体系

一、突破默认序列化的桎梏 1.1 原生序列化器的致命缺陷 Kafka默认提供的StringSerializer/ByteArraySerializer在复杂场景下暴露三大痛点&#xff1a; 类型安全黑洞&#xff1a;字节流缺乏元数据描述&#xff0c;消费端解析如履薄冰版本兼容困境&#xff1a;数据结构变更导致…

向量数据库与传统数据库的差异

向量数据库是一种专门设计用于高效存储、管理和检索**向量数据&#xff08;高维数值数组&#xff09;**的数据库系统。它针对非结构化数据&#xff08;如图像、文本、音频&#xff09;的特征进行优化&#xff0c;通过将数据转化为向量嵌入&#xff08;embeddings&#xff09;&a…

自动化框架的设计与实现

一、自动化测试框架 在大部分测试人员眼中只要沾上“框架”&#xff0c;就感觉非常神秘&#xff0c;非常遥远。大家之所以觉得复杂&#xff0c;是因为落地运用起来很复杂&#xff1b;每个公司&#xff0c;每个业务及产品线的业务流程都不一样&#xff0c;所以就导致了“自动化…

SpringBoot 3+ Lombok日志框架从logback改为Log4j2

r要将Spring Boot 3项目中的日志框架从Logback切换到Log4j2&#xff0c;并配置按日期滚动文件和控制台输出&#xff0c;请按照以下步骤操作&#xff1a; 步骤 1&#xff1a;排除Logback并添加Log4j2依赖 在pom.xml中修改依赖&#xff1a; <dependencies><!-- 排除默…

①、环境准备-主流技术(IPS/FW/主备-主主快速切换)

主流技术&(IPS/FW/主备-主主快速切换&#xff09; 一、RBM主备方案 RBM-FW-P 主配置内容介绍-注释 remote-backup group 含义&#xff1a;定义了一个远程备份组。这表明设备支持某种形式的远程备份功能&#xff0c;用于在设备之间同步配置或数据。data-channel interface …

量化交通拥堵

指数&#xff1a; 基于严重拥堵里程比的指数和基于出行时间比的指数。 评价指标是饱和度&#xff08;VC比&#xff09;&#xff0c;它表示交通量与通行能力的比值。 饱和度可分为道路饱和度和路口饱和度。道路饱和度还会进一步分级&#xff0c;有四档和六档之分。 城市道路和…

PDF与Markdown的量子纠缠:一场由VLM导演的文档界奇幻秀

缘起:当格式界的"泰坦尼克号"撞上"黑客帝国" 某个月黑风高的夜晚,在"二进制酒吧"的霓虹灯下: PDF(西装革履地晃着威士忌): “我的每一页都像瑞士手表般精密,连华尔街的秃鹫都为我倾倒!” Markdown(穿着带洞的拖鞋): “得了吧老古董!…

【neo4j数据导出并在其他电脑导入】

停止服务 neo4j stop 导出 neo4j-admin database dump neo4j --to-path"C:\Users\12901\Downloads\test folder" 导入 将 .dump 文件放在一个目录中 mkdir /root/dump-directory mv /root/neo4j.dump /root/dump-directory/ 使用包含 .dump 文件的目录路径作为 …

前端使用WPS WebOffice 做在线文档预览与编辑

先附上官网 WebOffice SDK 1、在下面这个地方找到jdk&#xff0c;然后下载 按照 2、只需要把jdk下载下来&#xff0c;放到项目中&#xff0c;然后引入到项目中就可以了&#xff0c;在wps 官网创建个应用&#xff0c;然后把appId放到代码中就可以了&#xff0c;等待后端把回调…

跨语言微服务架构(Java、Python)——“API中台”

文章目录 一、引言二、系统架构概述2.1 统一单点登录&#xff08;SSO&#xff09;与权限管理设计2.2 API中台与数据中台的融合2.3 跨语言适配器与 JWT 认证机制 三、技术细节与工具选型3.1 SSO 系统的选型与实现3.2 微服务架构与 API 中台的实现3.3 跨语言适配器实现与技术难点…

DeepSeek V3-0324升级:开启人机共创新纪元

一、技术平权&#xff1a;开源协议重构AI权力格局 DeepSeek V3选择MIT协议开源6850亿参数模型&#xff0c;本质上是一场针对技术垄断的“数字起义”。这一决策的深层影响在于&#xff1a; 商业逻辑的重构 闭源AI公司依赖API收费的商业模式面临根本性挑战。当顶级模型能力可通过…

QOpenGLWidget视频画面上绘制矩形框

一、QPainter绘制 在QOpenGLWidget中可以绘制,并且和OpenGL的内容叠在一起。paintGL里面绘制完视频后,解锁资源,再用QPainter绘制矩形框。这种方式灵活性最好。 void VideoGLWidget::paintGL() {glClear(GL_COLOR_BUFFER_BIT);m_program.bind();//绘制视频数据// 解绑VAOg…

3.3 Taylor公式

1.定义 1.1 taylor公式 1.2 麦克劳林公式 1.3 推论 1.4 拉格朗日余项和皮亚诺型余项 2. 例题 3.几种特殊函数的麦克劳林展开

CEF 给交互函数, 添加控制台是否显示交互参数log开关

CEF 控制台添加一函数,枚举 注册的供前端使用的CPP交互函数有哪些 CEF 多进程模式时,注入函数,获得交互信息-CSDN博客 这两篇文章,介绍了注入函数,在控制台中显示 各自提供的交互函数信息。 有些场景下,我们还需要更详细的信息,比如想知道 彼此传递的参数, 如果每次调…

QTcpSocket多线程连接慢问题

20250325记录 环境&#xff1a;Qt5.14.2 64位 msvc编译 在多线程环境下&#xff0c;使用QTcpSocket实现客户端&#xff0c;发现在少部分电脑上&#xff0c;连接时间过长&#xff0c;定时器检查套接字状态时&#xff0c;发现连接处于QAbstractSocket::ConnectingState状态。 …

IntelliJ IDEA创建Maven工程

1、创建空工程 1&#xff09;创建 2&#xff09;配置JDK和Maven 2、创建Maven工程 3、Maven工程结构简介 1&#xff09;目录 pom.xml 2&#xff09;窗口 4、参考 08.IDEA配置本地Maven软件_哔哩哔哩_bilibili

(UI自动化测试web端)第二篇:元素定位的方法_css定位之class选择器

看代码里的【find_element_by_css_selector( )】( )里的表达式怎么写&#xff1f; 文章介绍了第二种写法class选择器。你要根据网页中的实际情况来判断自己到底要用哪一种方法来进行元素定位。每种方法都要多练习&#xff0c;全都熟了之后你在工作当中使用起来元素定位时&#…

加新题了,MySQL 8.0 OCP 认证考试 题库更新

MySQL 8.0 OCP 认证考试 题库更新 MySQL 8.0 Database Administrator 考试科目&#xff1a;1Z0-908 近期发现&#xff0c;MySQL OCP认证考试题库发生变化&#xff0c;出现了很多新题&#xff0c;对此&#xff0c;CUUG专门收集整理了最新版本的MySQL考试原题&#xff0c;并会给…

基于JavaWeb的图书管理系统(SSM框架)

有需要请加文章底部Q哦 可远程调试 基于JavaWeb的图书管理系统(SSM框架) 一 介绍 此图书管理系统基于Java(SSM框架)开发&#xff0c;数据库mysql&#xff0c;前端bootstrap。系统角色分为用户和管理员。 技术栈&#xff1a;Javaweb(SpringSpringMVCMyBatis)MavenMySQLIDEA 二…

Google Benchmark性能测试

Google Benchmark性能测试 Google Benchmark 是一个用于 C 的微基准测试框架&#xff0c;专为测量小块代码的性能而设计。它提供了一种简单而强大的方式来编写、运行和分析基准测试&#xff0c;帮助开发人员识别性能瓶颈并优化代码。本教程将从安装和基本用法开始&#xff0c;…