当前位置: 首页 > article >正文

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 初始值为 0
  const [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 为 0
    return (
        <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>
原文地址:https://blog.csdn.net/zy010101/article/details/146543140
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.kler.cn/a/608381.html

相关文章:

  • 深度学习基础-----神经⽹络与深度学习((美)MichaelNielsen )
  • Java多线程与JConsole实践:从线程状态到性能优化!!!
  • 郭英成以茶会友对话李开复,探讨AI科技赋能
  • 第十六章:Specialization and Overloading_《C++ Templates》notes
  • 基于微信小程序的健身小助手设计与实现【lw+源码+部署+讲解】
  • DS足球监控【比分直播】监控,钉钉实现自动提醒
  • rocketmq零拷贝技术底层实现
  • Java Web开发基础-Servlet
  • CentOS 7 Yum 源配置与使用手册
  • PHP框架 ThinkPHP 漏洞探测分析
  • 简单聊聊Oracle和MySQL数据库的区别和使用场景
  • Spring IOC核心详解:掌握控制反转与依赖注入
  • java接口中 使用@RequestParam和@RequestPart区别
  • rudux中间件
  • 数据库基础知识点(系列五)
  • 分数线划定(信息学奥赛一本通-1180)
  • 关于跨域问题(本地前端访问服务器端接口跨域出错)
  • 解析信息归属地与网络安全的关联
  • 重复出现的数字
  • 无人机中继传输数据链技术,(无人机+自组网)远距离传输技术实现详解