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.rhkb.cn/news/41234.html

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

相关文章

比特币等虚拟货币实时价格使用说明,数字货币价格获取,k线获取,实时价格获取

数据截图 k线数据 websocket 实时价格数据 根据这些数据可以做出自己的产品 获取时间段内的k线数据 在开始之前&#xff0c;你需要知道的知识&#xff1a; 币种缩写英文名币种IDBTCBitcoinbitcoinETHEthereumethereumEOSEOSeosUSDTTethertetherLTCLitecoinlitecoinUSDDol…

初阶7 vector

本章重点 vector的介绍vector的使用vector的模拟实现 1.vector的介绍 vector就类似数据结构中的顺序表 vector是表示可变大小数组的序列容器。 就像数组一样&#xff0c;vector也采用的连续存储空间来存储元素。 意味着可以采用下标对vector的元素 进行访问&#xff0c;和数…

解码未来:DeepSeek开源FlashMLA,推理加速核心技术,引领AI变革

前言&#xff1a; DeepSeek 兑现了自己的诺言&#xff0c;开源了一款用于 Hopper GPU 的高效型 MLA 解码核&#xff1a;FlashMLA。 项目地址&#xff1a;https://github.com/deepseek-ai/FlashMLA 1:FlashMLA 是什么呀&#xff1f; MLA是DeepSeek大模型的重要技术创新点&…

scss预处理器对比css的优点以及基本的使用

本文主要在vue中演示&#xff0c;scss的基本使用。安装命令 npm install sass sass-loader --save-dev 变量 SCSS 支持变量&#xff0c;可将常用的值&#xff08;如颜色、字体大小、间距等&#xff09;定义为变量&#xff0c;方便重复使用和统一修改。 <template><…

GPU架构与通信互联技术介绍

文章目录 GPU架构介绍SM 和 Warp Scheduler GPU通信互联技术介绍1、GPUDirectGPUDirect Shared AccessGPUDirect P2PGPUDirect for VideoGPUDirect for RDMARDMAGPUDirect RDMA GPUDirect Storage 2、NVLink & NVSwitchNVLinkNVSwitch 3、应用场景总结 GPU架构介绍 SM 和 …

强化学习与神经网络结合(以 DQN 展开)

目录 基于 PyTorch 实现简单 DQN double DQN dueling DQN Noisy DQN&#xff1a;通过噪声层实现探索&#xff0c;替代 ε- 贪心策略 Rainbow_DQN如何计算连续型的Actions 强化学习中&#xff0c;智能体&#xff08;Agent&#xff09;通过与环境交互学习最优策略。当状态空间或动…

day 16

创建链接文件 软链接&#xff1a;又叫符号链接&#xff0c;类似win的快捷方式&#xff0c;是一种用来建立文件的特殊文件&#xff0c;这个文件里的数据都是建立链接的文件&#xff0c;但是它和建立链接的文件不是一个东西&#xff0c;如果建立链接的文件移动或删除&#xff0c…

fork系统调用

基本概念&#xff1a; 在操作系统里&#xff0c;进程是正在运行的程序的实例。fork() 函数的作用是复制当前进程&#xff0c;生成一个新的进程&#xff0c;这个新进程被称作子进程&#xff0c;而原本的进程则是父进程。这两个进程&#xff08;父进程和子进程&#xff09;会从 …

【leetcode刷题记录】(java)数组 链表 哈希表

文章目录 四、题目之&#xff1a;代码随想录(1) 代码随想录&#xff1a;数组[704. 二分查找](https://leetcode.cn/problems/binary-search/)[27. 移除元素](https://leetcode.cn/problems/remove-element/)暴力解:双指针&#xff1a; [977. 有序数组的平方](https://leetcode.…

在线运行vscode

安装 https://github.com/coder/code-server?utm_sourcesyndication&pubDate20250317 运行前预览脚本 curl -fsSL https://code-server.dev/install.sh | sh -s -- --dry-run运行脚本 curl -fsSL https://code-server.dev/install.sh | sh其他 可以通过后台服务运行&am…

【Tauri2】002——Cargo.toml和入口文件

目录 前言 正文 toml文件的基础 注释——# Comment 键值对——Key/Value 表——[table] 内联表——Inline Table 数组——Array package和crate Cargo.toml文件 Cargo.toml——dependencies Cargo.toml——lib crate-type main.rs 前言 【Tauri2】001——安装及…

Netty源码—7.ByteBuf原理三

大纲 9.Netty的内存规格 10.缓存数据结构 11.命中缓存的分配流程 12.Netty里有关内存分配的重要概念 13.Page级别的内存分配 14.SubPage级别的内存分配 15.ByteBuf的回收 9.Netty的内存规格 (1)4种内存规格 (2)内存申请单位 (1)4种内存规格 一.tiny&#xff1a;表示从…

W、M、C练题笔记(持续更新中)

web here are the flag 点击&#xff0c;页面跳转404.php&#xff0c;用bp抓包访问/flag.php页面&#xff0c;得到flag用base64解码 TryToFindFlag 打开后查看源代码 发现是robots协议&#xff0c;访问robots.txt 访问flllaaa......&#xff0c;得到空白页面&#xff0c;查看…

【高项】信息系统项目管理师(十二)项目干系人管理【3分】

项目干系人管理包括识别能够影响项目或会受项目影响的人员、团队或组织,分析干系人对项目的期望和影响,制定管理策略有效调动干系人参与项目决策和执行。项目干系人管理过程能够支持项目团队的工作。一、管理基础 1、管理的重要性 项目经理和团队管理干系人的能力决定着项目…

Keil(ARMCC)编译改为Cmake(GNU)编译

1. 环境介绍&#xff1a; 某款ARM-M4芯片&#xff08;应该芯片通用&#xff09;cmkeGNUNinja&#xff08;CLion&#xff09; 2. 必备&#xff1a; 芯片启动文件 startup_xxxx.s链接文件 xxxx_flash.ldCMakeLists.txt 3. 具体修改步骤 第一步&#xff1a;观察启动文件…

SpringCould微服务架构之Docker(4)

Docker ce是社区版。 安装docker之前&#xff0c;先安装yum-util 。 安装docker之前&#xff0c;一定要先关闭防火墙。

LangChain开发(四)服务监控(LangSmith、verbose、debug)

文章目录 LangChain服务监控LangSmith Tracing&#xff08;跟踪&#xff09;Verbose&#xff08;1详细日志打印&#xff09;Debug&#xff08;调试日志打印&#xff09;源码地址参考资料 LangChain服务监控 与构建任何类型的软件一样&#xff0c;使用LLM构建时&#xff0c;总会…

从车间到数字生态:MES如何引领制造业智能化革命‌

在全球制造业加速迈向工业4.0的浪潮中&#xff0c;传统生产模式正经历颠覆性变革。制造执行系统&#xff08;MES&#xff09;作为连接物理车间与数字世界的核心纽带&#xff0c;正从“生产辅助工具”升级为“智能决策大脑”&#xff0c;推动制造业向数据驱动、柔性化与可持续化…

人工智能之数学基础:瑞利商的推广形式——广义瑞利商

本文重点 在数学和工程领域,瑞利商(Rayleigh quotient)的推广形式——广义瑞利商(Generalized Rayleigh quotient)扮演着重要的角色。它们不仅为线性代数中的特征值问题提供了新的视角,还在信号处理、机器学习、计算机视觉等领域有广泛的应用。 广义瑞利商的定义 广义…

【QT】QT中的中文显示乱码解决

QT中的中文显示乱码解决 1.编辑栏左键——>选择编码 2.选择UTF-8—>按编码重新载入 3.工具栏左键—>选择选项 4.同样选择UTF-8—>确定即可