React四官方文档总结一UI与交互

代码下载

React官网已经都是函数式组件文档,没有类组件文档,但是还是支持类组件这种写法。

UI 描述

组件

组件 是 React 的核心概念之一,它们是构建用户界面(UI)的基础。React 允许你将标签、CSS 和 JavaScript 组合成自定义“组件”,即 应用程序中可复用的 UI 元素。

React 最为重视交互性且使用了相同的处理方式:React 组件是一段可以 使用标签进行扩展 的 JavaScript 函数。

组件可以渲染其他组件,但是 请不要嵌套他们的定义。当子组件需要使用父组件的数据时,你需要 通过 props 的形式进行传递,而不是嵌套定义。

JSX

每个 React 组件都是一个 JavaScript 函数,它会返回一些标签,React 会将这些标签渲染到浏览器上。React 组件使用一种被称为 JSX 的语法扩展来描述这些标签。JSX 看起来和 HTML 很像,但它的语法更加严格并且可以动态展示信息。了解这些区别最好的方式就是将一些 HTML 标签转化为 JSX 标签。

JSX and React 是相互独立的 东西。但它们经常一起使用,但你 可以 单独使用它们中的任意一个,JSX 是一种语法扩展,而 React 则是一个 JavaScript 的库。

JSX 规则
  1. 只能返回一个根元素,如果想要在一个组件中包含多个元素,需要用一个父标签把它们包裹起来,如果你不想在标签中增加一个额外的 <div>,可以用 <></> 元素来代替。
  2. 标签必须闭合,JSX 要求标签必须正确闭合。像 <img> 这样的自闭合标签必须书写成 <img />,而像 <li>oranges 这样只有开始标签的元素必须带有闭合标签,需要改为 <li>oranges</li>
  3. 使用驼峰式命名法给 所有 大部分属性命名! JSX 最终会被转化为 JavaScript,而 JSX 中的属性也会变成 JavaScript 对象中的键值对。但 JavaScript 对变量的命名有限制。例如,变量名称不能包含 - 符号或者像 class 这样的保留字。

由于历史原因,aria-* 和 data-* 属性是以带 - 符号的 HTML 格式书写的。

转化器 将 HTML 和 SVG 标签转化为 JSX。

在 JSX 中通过大括号使用 JavaScript

在 JSX 中,只能在以下两种场景中使用大括号:

  • 用作 JSX 标签内的文本:<h1>{name}'s To Do List</h1> 是有效的,但是 <{tag}>Gregorio Y. Zara's To Do List</{tag}> 无效。
  • 用作紧跟在 = 符号后的 属性:src={avatar} 会读取 avatar 变量,但是 src="{avatar}" 只会传一个字符串 {avatar}

props

React 组件使用 props 来互相通信。每个父组件都可以提供 props 给它的子组件,从而将一些信息传递给它。可以通过它们传递任何 JavaScript 值,包括对象、数组和函数。

可以通过解构语法来读取 props 的值,也可以通过在参数后面写 = 和默认值来进行解构:

function Avatar({ person, size = 100 }) {// ...
}

一些组件将它们所有的 props 转发给子组件,因为这些组件不直接使用他们本身的任何 props,所以使用更简洁的“展开”语法是有意义的:

function Profile(props) {return (<div className="card"><Avatar {...props} /></div>);
}

条件渲染

在一些情况下,不想有任何东西进行渲染,可以直接返回 null。

JavaScript && 表达式 的左侧(我们的条件)为 true 时,它则返回其右侧的值(在我们的例子里是勾选符号)。但条件的结果是 false,则整个表达式会变成 false。在 JSX 里,React 会将 false 视为一个“空值”,就像 null 或者 undefined,这样 React 就不会在这里进行任何渲染。

列表渲染 key

必须给数组中的每一项都指定一个 key——它可以是字符串或数字的形式,只要能唯一标识出各个数组项就行。key 会告诉 React,每个组件对应着数组里的哪一项,所以 React 可以把它们匹配起来。这在数组项进行移动(例如排序)、插入或删除等操作时非常重要。一个合适的 key 可以帮助 React 推断发生了什么,从而得以正确地更新 DOM 树。

不同来源的数据往往对应不同的 key 值获取方式:

  • 来自数据库的数据: 如果你的数据是从数据库中获取的,那你可以直接使用数据表中的主键,因为它们天然具有唯一性。
  • 本地产生数据: 如果你数据的产生和保存都在本地(例如笔记软件里的笔记),那么你可以使用一个自增计数器或者一个类似 uuid 的库来生成 key。

key 需要满足的条件:

  • key 值在兄弟节点之间必须是唯一的。 不过不要求全局唯一,在不同的数组中可以使用相同的 key。
  • key 值不能改变,否则就失去了使用 key 的意义!所以千万不要在渲染时动态地生成 key。

React 中为什么需要 key?key 让我们可以从众多的兄弟元素中唯一标识出某一项 JSX 节点。而一个精心选择的 key 值所能提供的信息远远不止于这个元素在数组中的位置。即使元素的位置在渲染的过程中发生了改变,它提供的 key 值也能让 React 在整个生命周期中一直认得它。

陷阱:可能会想直接把数组项的索引当作 key 值来用,实际上,如果你没有显式地指定 key 值,React 确实默认会这么做。但是数组项的顺序在插入、删除或者重新排序等操作中会发生改变,此时把索引顺序用作 key 值会产生一些微妙且令人困惑的 bug。与之类似,请不要在运行过程中动态地产生 key,像是 key={Math.random()} 这种方式。这会导致每次重新渲染后的 key 值都不一样,从而使得所有的组件和 DOM 元素每次都要重新创建。这不仅会造成运行变慢的问题,更有可能导致用户输入的丢失。所以,使用能从给定数据中稳定取得的值才是明智的选择。

注意:组件不会把 key 当作 props 的一部分。Key 的存在只对 React 本身起到提示作用。如果你的组件需要一个 ID,那么请把它作为一个单独的 prop 传给组件: <Profile key={id} userId={id} />

保持组件纯粹

在计算机科学中(尤其是函数式编程的世界中),纯函数 通常具有如下特征:

  • 只负责自己的任务。它不会更改在该函数调用前就已存在的对象或变量。
  • 输入相同,则输出相同。给定相同的输入,纯函数应总是返回相同的结果。

在渲染过程中,组件改变了 预先存在的 变量的值,将这种现象称为 突变(mutation) 。纯函数不会改变函数作用域外的变量、或在函数调用前创建的对象——这会使函数变得不纯粹!

React 的渲染过程必须自始至终是纯粹的。组件应该只 返回 它们的 JSX,而不 改变 在渲染前,就已存在的任何对象或变量 — 这将会使它们变得不纯粹!但是可以在渲染时更改刚刚 创建的变量和对象:

function Cup({ guest }) {return <h2>Tea cup for guest #{guest}</h2>;
}export default function TeaGathering() {let cups = [];for (let i = 1; i <= 12; i++) {cups.push(<Cup key={i} guest={i} />);}return cups;
}

每次渲染时都是在 TeaGathering 函数内部创建的它们。TeaGathering 之外的代码并不会知道发生了什么。这就被称为 “局部 mutation” — 如同藏在组件里的小秘密。

函数式编程在很大程度上依赖于纯函数,但 某些事物 在特定情况下不得不发生改变这些变动包括更新屏幕、启动动画、更改数据等,它们被称为 副作用。它们是 “额外” 发生的事情,与渲染过程无关。在 React 中,副作用通常属于 事件处理程序。事件处理程序是 React 在执行某些操作(如单击按钮)时运行的函数。即使事件处理程序是在你的组件 内部 定义的,它们也不会在渲染期间运行! 因此事件处理程序无需是纯函数。

将 UI 视为树

React 以及许多其他 UI 库,将 UI 建模为树。将应用程序视为树对于理解组件之间的关系以及调试性能和状态管理等未来将会遇到的一些概念非常有用。树是项目和 UI 之间的关系模型,通常使用树结构来表示 UI。

渲染树表示 React 应用程序的单个渲染过程。在 条件渲染 中,父组件可以根据传递的数据渲染不同的子组件。尽管渲染树可能在不同的渲染过程中有所不同,但通常这些树有助于识别 React 应用程序中的顶级和叶子组件。顶级组件是离根组件最近的组件,它们影响其下所有组件的渲染性能,通常包含最多复杂性。叶子组件位于树的底部,没有子组件,通常会频繁重新渲染。识别这些组件类别有助于理解应用程序的数据流和性能。

模块依赖树

在 React 应用程序中,可以使用树来建模的另一个关系是应用程序的模块依赖关系。当 拆分组件 和逻辑到不同的文件中时,就创建了 JavaScript 模块,在这些模块中可以导出组件、函数或常量。模块依赖树中的每个节点都是一个模块,每个分支代表该模块中的 import 语句。

与同一应用程序的渲染树相比,存在相似的结构,但也有一些显著的差异:

  • 构成树的节点代表模块,而不是组件。
  • 非组件模块,在这个树中也有所体现。渲染树仅封装组件。
  • 组件可以 接受 JSX 作为 children props,因此它将 其他组件 作为子组件渲染,但不导入该模块。

在为生产环境构建 React 应用程序时,通常会有一个构建步骤,该步骤将捆绑所有必要的 JavaScript 以供客户端使用。负责此操作的工具称为 bundler(捆绑器),并且 bundler 将使用依赖树来确定应包含哪些模块。随着应用程序的增长,捆绑包大小通常也会增加。大型捆绑包大小对于客户端来说下载和运行成本高昂,并延迟 UI 绘制的时间。了解应用程序的依赖树可能有助于调试这些问题。

交互

useState

在 React 中,useState 以及任何其他以“use”开头的函数都被称为 Hook。Hook 是特殊的函数,只在 React 渲染时有效。它们能让你 “hook” 到不同的 React 特性中去。

Hooks ——以 use 开头的函数——只能在组件或自定义 Hook 的最顶层调用。 不能在条件语句、循环语句或其他嵌套函数内调用 Hook。Hook 是函数,但将它们视为关于组件需求的无条件声明会很有帮助。在组件顶部 “use” React 特性,类似于在文件顶部“导入”模块。

State 是屏幕上组件实例内部的状态。换句话说,如果你渲染同一个组件两次,每个副本都会有完全隔离的 state!改变其中一个不会影响另一个。

Hook 是能让你的组件使用 React 功能的特殊函数(状态是这些功能之一)。useState Hook 让你声明一个状态变量。它接收初始状态并返回一对值:当前状态,以及一个让你更新状态的设置函数。

function StateHook() {const [index, setIndex] = React.useState(0)return (<><p>index: {index}</p><button onClick={() => {setIndex(index + 1)console.log('index: ', index);}}>+1</button></>)
}
ReactDOM.createRoot(document.getElementById('stateHook')).render(<StateHook></StateHook>)

状态的行为更像一个快照。设置它并不改变已有的状态变量,而是触发一次重新渲染。可以通过在设置状态时传递一个 更新器函数 来解决这个问题,在需要排队进行多次状态更新,那么这非常方便:

      setIndex(index + 1)setIndex(i => i + 1)setIndex((i, p) => {// 不支持第二个参数 pconsole.log('i: ', i, 'p: ', p);return i + 1// 不支持 更新后的回调函数}, () => console.log('i: ', index))

注意:与类组件 setState 不同的是 useState 更新器函数只有一个参数就是最新的状态值,并且不支持更新回调函数。类组件的 setState 是异步更新数据而 useState 状态的行为更像一个快照,通过延时函数就可以看出他们的差别,一个 useState 变量的值永远不会在一次渲染的内部发生变化, 即使其事件处理函数的代码是异步的:

class StateCom extends React.Component {state = { index: 0 }render() {return (<><p>index: {this.state.index}</p><button onClick={() => {this.setState({index: this.state.index + 1})setTimeout(() => {// 输出 1console.log('index: ', this.state.index);}, 2000);}}>+1</button></>)}
}
function UseStateCom() {const [i, setIndex] = useState(0)return (<><p>index: {i}</p><button onClick={() => {setIndex(i + 1)setTimeout(() => {// 输出 0console.log('index: ', i);}, 2000);}}>+1</button></>)
}

严格来说 React state 中存放的对象是可变的,但你应该像处理数字、布尔值、字符串一样将它们视为不可变的,因此应该替换它们的值,而不是对它们进行修改。数组只是另一种对象。同对象一样,需要将 React state 中的数组视为只读的。这意味着你不应该使用类似于 arr[0] = ‘bird’ 这样的方式来重新分配数组中的元素,也不应该使用会直接修改原始数组的方法,例如 push() 和 pop()。

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

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

相关文章

一个简单的Http根据规则自动路由

在日常项目中&#xff0c;有时候会根据一些规则/标识进行Http路由匹配&#xff0c;下面我实现一个简单的Http根据systemCode自动路由&#xff1b; ControllerServicePropertiesProperties类Yaml 测试路由到baidu Controller import com.example.demo.service.GatewayRoutingS…

Windows安装PM2 注意事项与错误查改

Windows安装 1. 首先应确保 node 和 npm 已经安装&#xff1a; node -v #查看 node 版本 npm -v #查看 npm 版本注意有时候即使npm安装了&#xff0c;但并没有进行配置环境变量&#xff0c;后面会将如何配置。 2. 尝试安装pm2到全局路径 运行以下命令对 PM2 进行全局安装&a…

Mycat2安装配置

安装配置 安装 目前Mycat2下载地址已经不可访问&#xff0c;安装包可从参考资料[1]获取 下载后解压zip文件&#xff0c;将jar放在lib目录下 编辑配置文件 编辑conf文件夹下的prototypeDs.datasource.json 更改数据库相关信息 启动 windows环境下启动Mycat 以管理员身份运行…

查找算法和排序算法

文章目录 1.基本查找1.1需求一:1.2需求二: 2.二分查找3.分块查找3.1分块查找的扩展 4.冒泡排序5.选择排序6.插入排序7.快速排序(递归算法) 1.基本查找 在数组或集合中挨个元素查找需要的元素 1.1需求一: 需求:定义一个方法利用基本查找,查询某个元素是否存在 数据如下&#…

威胁 Windows 和 Linux 系统的新型跨平台勒索软件:Cicada3301

近年来&#xff0c;网络犯罪世界出现了新的、日益复杂的威胁&#xff0c;能够影响广泛的目标。 这一领域最令人担忧的新功能之一是Cicada3301勒索软件&#xff0c;最近由几位网络安全专家进行了分析。他们有机会采访了这一危险威胁背后的勒索软件团伙的成员。 Cicada3301的崛…

微信小程序中关闭默认的 `navigationBar`,并使用自定义的 `nav-bar` 组件

要在微信小程序中关闭默认的 navigationBar&#xff0c;并使用自定义的 nav-bar 组件&#xff0c;你可以按照以下步骤操作&#xff1a; 1. 关闭默认的 navigationBar 在你的页面的配置文件 *.json 中设置 navigationBar 为 false。你需要在页面的 JSON 配置文件中添加以下代码…

C#从零开始学习(用户界面)(unity Lab4)

这是书本中第四个unity Lab 在这次实验中,将学习如何搭建一个开始界面 分数系统 点击球,会增加分数 public void ClickOnBall(){Score;}在OneBallBehaviour类添加下列方法 void OnMouseDown(){GameController controller Camera.main.GetComponent<GameController>();…

纯血鸿蒙的未来前景

纯血鸿蒙作为华为推出的新一代操作系统&#xff0c;其未来的发展前景可以从多个方面进行分析。 从技术角度来看&#xff0c;纯血鸿蒙实现了全面的自主可控。它去除了传统的AOSP代码&#xff0c;仅支持鸿蒙内核和鸿蒙系统的应用&#xff0c;不再兼容安卓OS。这种技术上的独立性…

js纯操作dom版购物车(实现购物车功能)

代码&#xff1a; <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>Document</title>&l…

华为HCIE-OpenEuler认证详解

华为HCIE认证&#xff08;Huawei Certified ICT Expert&#xff09;是华为提供的最高级别的专业认证&#xff0c;它旨在培养和认证在特定技术领域具有深厚理论知识和丰富实践经验的专家级工程师。对于华为欧拉&#xff08;OpenEuler&#xff09;方向的HCIE认证&#xff0c;即HC…

jenkins国内插件源

Jenkins是一个开源的持续集成和持续部署&#xff08;CI/CD&#xff09;工具, 可以大大减轻部署的工作量, 但是jenkins作为一个国外的软件, 在国内下载插件会很麻烦, 因此我们可以将其换为国内源 更换步骤 替换国内插件下载地址 以linux为例 首先, jenkins初始化完成之后不会…

如何制作一台自己想要的无人机?无人机改装调试技术详解

制作一台符合个人需求的无人机并对其进行改装调试&#xff0c;是一个既具挑战性又充满乐趣的过程。以下是从设计、选购材料、组装、调试到改装的详细步骤&#xff1a; 一、明确需求与设计 1. 明确用途与性能要求&#xff1a; 确定无人机的使用目的&#xff0c;如航拍、比赛、…

推荐一款功能强大的数据备份工具:Iperius Backup Full

Iperius Backup是一款非常灵活而且功能强大的数据备份工具&#xff0c;程序可以非常好的保护您的文件和数据的安全。支持DAT备份、LTO备份、NAS备份、磁带备份、RDX驱动器、USB备份、并且支持zip压缩和军事级别的AES 256位数据加密技术! 主要特色 云备份 Iperius可以自动地发…

如何训练 RAG 模型

训练 RAG&#xff08;Retrieval-Augmented Generation&#xff09;模型涉及多个步骤&#xff0c;包括准备数据、构建知识库、配置检索器和生成模型&#xff0c;以及进行训练。以下是一个详细的步骤指南&#xff0c;帮助你训练 RAG 模型。 1. 安装必要的库 确保你已经安装了必…

.net 根据html的input type=“week“控件的值获取星期一和星期日的日期

初始化 "week" 控件值&#xff1a; //MVC部分 public ActionResult WeeklyList() {int weekNo new GregorianCalendar().GetWeekOfYear(System.DateTime.Now, System.Globalization.CalendarWeekRule.FirstDay, DayOfWeek.Sunday);string DefaultWeek DateTime.No…

洛谷 P1130 红牌

自用。 题目传送门&#xff1a;红牌 - 洛谷 题解&#xff1a;Inori_333 参考题解&#xff1a;无 /*P1130 红牌https://www.luogu.com.cn/problem/P11302024/10/25 submit:inori_333 */#include <iostream> using namespace std; int n, m;//n步&#xff0c;m个小组 …

代码随想录算法训练营Day39 | 卡玛网-46.携带研究材料、416. 分割等和子集

目录 卡玛网-46.携带研究材料 416. 分割等和子集 卡玛网-46.携带研究材料 题目 卡玛网46. 携带研究材料&#xff08;第六期模拟笔试&#xff09; 题目描述&#xff1a; 小明是一位科学家&#xff0c;他需要参加一场重要的国际科学大会&#xff0c;以展示自己的最新研究成…

论文速读:YOLO-G,用于跨域目标检测的改进YOLO(Plos One 2023)

原文标题&#xff1a;YOLO-G: Improved YOLO for cross-domain object detection 中文标题&#xff1a;YOLO-G&#xff1a;用于跨域目标检测的改进YOLO 论文地址&#xff1a; 百度网盘 请输入提取码 提取码&#xff1a;z8h7 代码地址&#xff1a; GitHub - airy975924806/yolo…

使用js-enumerate报错Cannot set properties of undefined

环境 node v16.20.2react 18.3.1react-scripts 5.0.1 按照最新 npx create-react-app my-app 创建出来的新项目&#xff0c;引入 js-enumerate 库后运行报错。 报错 Uncaught runtime errors:ERROR Cannot set properties of undefined (setting Enum) TypeError: Cannot se…

【electron7】调试对话图片的加密处理

1.图片加解密的公共数据&#xff1a;key、iv等 // 字符串转字节数组的方法 const stringToBytes (str: string) > {let ch 0let st []let re: any[] []for (let i 0; i < str.length; i) {ch str.charCodeAt(i) // get charst [] // set up "stack"do …