React动态渲染:如何用map循环渲染一个列表(List)

React动态渲染:如何用map循环渲染一个列表(List)?

系列回顾:
在上一篇中,我们学习了如何通过onClick等事件处理,让React应用响应用户的操作。现在我们的组件已经能“听懂话”了。但是,目前为止我们展示的内容都是写死的。如果我们要展示一个从服务器获取的朋友列表,或者一个包含100件商品的清单,总不能在代码里一个一个地手写<li>标签吧?

欢迎来到React学习的第五站!

今天,我们要学习一个非常实用且强大的技能:如何根据一组数据(通常是一个数组),动态地渲染出一个列表。 这项技能将让你能够构建出内容丰富的、由数据驱动的Web应用。

我们将要使用的核心工具,是JavaScript中一个非常强大的数组方法:.map()

核心思想:数据与UI的映射

在React中,我们不直接操作DOM。我们的思维方式是:
有一份数据(数组),就应该对应地生成一份UI(一组组件或元素)。

.map()方法就是实现这种“映射”关系的不二之P。它会遍历数组中的每一个元素,对每个元素执行你指定的操作,然后返回一个包含所有操作结果的新数组

在React中,这个“操作”通常就是:把一个数据项,转换成一个JSX元素(比如<li>


实战一:渲染一个简单的水果列表

让我们从一个简单的例子开始,我们有一个包含水果名称的数组,目标是把它们渲染成一个无序列表(<ul>)。

第一步:准备 App.jsx 和数据

清空 src/App.jsx,并写入以下代码。我们先在组件内部定义一个水果数组作为我们的数据源。

import './App.css';function App() {const fruits = ['苹果 🍎', '香蕉 🍌', '橙子 🍊', '草莓 🍓'];return (<div><h1>我的水果清单</h1><ul>{/* 我们将在这里动态渲染列表 */}</ul></div>);
}export default App;

第二步:使用 .map() 遍历数组并生成JSX

现在,我们在 <ul> 标签内部,使用花括号 {} 来嵌入JavaScript表达式。这个表达式就是我们的 .map() 操作。

修改return部分的代码:

function App() {const fruits = ['苹果 🍎', '香蕉 🍌', '橙子 🍊', '草莓 🍓'];return (<div><h1>我的水果清单</h1><ul>{fruits.map((fruit, index) => {return <li key={index}>{fruit}</li>;})}</ul></div>);
}

代码解释:

  1. {...}: 我们在JSX中打开了一个JavaScript代码块。
  2. fruits.map(...): 我们调用了fruits数组的map方法。
  3. (fruit, index) => { ... }: 这是一个箭头函数,它会被map方法在遍历数组时,对每个元素都调用一次。
    • fruit: 代表当前正在被遍历的元素(比如第一次是 ‘苹果 🍎’)。
    • index: 代表当前元素的索引(从0开始)。
  4. return <li key={index}>{fruit}</li>;: 这是最关键的一步。对于每一个fruit,我们都返回一个<li> JSX元素。{fruit}会把水果的名称显示出来。最终,map方法会返回一个由所有这些<li>元素组成的新数组,React会把这个数组渲染到DOM上。

第三步:查看效果

保存文件,回到浏览器。你会看到一个漂亮的水果列表已经整整齐齐地显示出来了!我们只写了几行代码,就动态地生成了整个列表。


深入理解:key 属性到底是什么?为什么它如此重要?

你可能已经注意到了,我们在<li>元素上添加了一个key={index}的属性。如果你不加这个key,程序虽然能运行,但浏览器控制台会给你一个红色的警告:Warning: Each child in a list should have a unique "key" prop.

key是React用来识别列表中每个元素的“身份证”。

当列表的数据发生变化时(比如添加、删除或重新排序),React需要一种高效的方式来找出哪些元素是新增的、哪些是删除了、哪些只是移动了位置,从而只对变化的部分进行最小化的DOM更新,而不是重新渲染整个列表。

key就是React进行这种“对比”的依据。

使用key的两个重要原则:

  1. key在兄弟元素之间必须是唯一的。 就像一个班级里,每个学生的学号都不能重复。
  2. key应该保持稳定。 它不应该随着项目的重新渲染而改变。

为什么不推荐使用索引(index)作为key
在上面的例子中,我们使用了index作为key。对于一个不会改变顺序、不会被删除或插入的静态列表,这是可以接受的。

但是,如果你的列表会发生变化,使用index作为key可能会导致严重的性能问题和一些奇怪的bug。想象一下,你删除了数组的第一个元素,原来索引为1的元素现在变成了索引为0,索引为2的变成了1…所有元素的key都变了!React会认为你修改了列表中的每一个元素,而不是只删除了一个。

最佳实践:使用数据中独一无二的ID作为key


实战二:渲染一个包含对象的列表(最佳实践)

在真实世界中,我们的数据通常是对象的数组,每个对象都有一个唯一的id

让我们修改一下案例,数据变成一个用户列表。

import './App.css';function App() {const users = [{ id: 1, name: '张三', age: 25 },{ id: 2, name: '李四', age: 30 },{ id: 3, name: '王五', age: 22 }];return (<div><h1>用户列表</h1><ul>{users.map(user => (// 使用每个用户的 id 作为 key<li key={user.id}>姓名: {user.name}, 年龄: {user.age}</li>))}</ul></div>);
}export default App;

代码解释:

  • 我们的数据源users现在是一个对象数组。
  • .map()中,我们直接使用user.id作为key。因为id是每个用户独有的,并且不会改变,所以这是最理想、最稳健的key
  • 我们还稍微简化了箭头函数,当函数体只有一行return语句时,可以省略{}return关键字。

总结与思考

今天,我们解锁了React中一项至关重要的技能——动态渲染列表。你现在已经能够将任何数组数据转换成漂亮的UI界面了。核心知识点回顾:

  1. 核心工具: JavaScript的**.map()**数组方法。
  2. 核心思想: 将数据数组映射为UI元素数组。
  3. key属性: 它是React识别列表项的“身份证”,在兄弟节点间必须是唯一稳定的。
  4. 最佳实践: 优先使用数据本身提供的唯一ID作为key

我们已经能根据数据批量生成UI了。但有时候,我们并不想显示所有内容,而是想根据某些条件来决定某个UI部分是否应该显示。例如,用户登录后才显示“欢迎信息”,或者数据正在加载时显示“加载中…”。

在下一篇文章 《React条件渲染:如何根据不同条件显示或隐藏一个组件?》 中,我们将学习如何控制UI的显示和隐藏逻辑,让我们的应用更加智能。我们下期再会!

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

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

相关文章

React Native【实战范例】水平滚动分类 FlatList

import React from "react"; import { FlatList, SafeAreaView, StyleSheet, Text, View } from "react-native"; interface itemType {id: string;title: string;icon: string; } // 水平滚动数据 const horizontalData: itemType[] [{ id: "1"…

iOS swiftUI的实用举例

SwiftUI 是 Apple 推出的声明式 UI 框架&#xff0c;以下是一些实用技巧和最佳实践&#xff0c;可以帮助你更高效地开发 iOS/macOS/watchOS/tvOS 应用。 1. 布局技巧 灵活的空间占用 // 使用 Spacer 填充可用空间 HStack {Text("Left")Spacer() // 填充中间空间 …

SpringMVC异步处理Servlet

使用SpringMVC异步处理Servlet解决的问题 可以不阻塞有限的tomcat 线程&#xff08;默认是200~250个&#xff0c;springboot3是200个&#xff09;&#xff0c;确保网络请求可以持续响应特定业务使用自定义线程池&#xff0c;可以处理的业务量更大对上层业务完全无感知&#xf…

同步与异步编程范式全景研究——从CPU时钟周期到云原生架构的范式演进

第一章 时空观的根本分歧 1.1 物理时间的约束性 同步操作的本质是对牛顿绝对时间的服从&#xff0c;其阻塞特性源于冯诺依曼体系下指令顺序执行的基因。现代CPU的流水线技术&#xff08;如Intel Hyper-Threading&#xff09;通过指令级并行实现伪异步&#xff0c;但开发者仍需…

【零散技术】5分钟完成Odoo18 登陆页面全自定义

序言:时间是我们最宝贵的财富,珍惜手上的每个时分 从最初的tinyERP到Open ERP&#xff0c;再由OpenERP到Odoo&#xff0c;虽然UI已经过了多次大改&#xff0c;Odoo登录界面依旧丑陋&#xff0c;同时还有各种Odoo版权信息&#xff0c;对于定制项目而言是不友好的。 今天以Odoo18…

Vue3 + TypeScript + Element Plus + el-pagination 分页查询实例分享

前端技术栈&#xff1a;Vue3 TypeScript Element Plus el-pagination 后端技术栈&#xff1a;Java Spring Boot Mybatis 应用异常情况说明&#xff1a;点击页码2&#xff0c;会发送两次请求&#xff0c;并且自动跳回页码1 代码&#xff1a; Reagent.vue <script set…

LoadRunner 2023 安装部署

下载地址&#xff1a;链接: https://caiyun.139.com/w/i/2nQQRYCZ1Ssjl 提取码:3gz0 复制内容打开139-云盘 主要下载Micro_Focus_LoadRunner_2023_Community_Edition.exe来安装就可以。 如要汉化&#xff0c;则再下载安装Language_Packs.exe的安装包 说明&#xff1a;LoadR…

ABC410 : F - Balanced Rectangles

https://atcoder.jp/contests/abc410/tasks/abc410_fhttps://atcoder.jp/contests/abc410/tasks/abc410_f首先可以一眼看出暴力 &#xff1a;枚举左上角和右下角&#xff0c;用前缀和算出矩形中#的数量&#xff0c;判断即可 但这样是,爆!!! 考虑优化&#xff0c;我们可以枚举…

嵌入式学习笔记 - HAL库对外设的封装

一 外设封装结构 HAL库对外设的封装使用了xx_HandleTypeDef类型的外设句柄结构体&#xff0c;这个句柄结构体的第一个成员Instance(xx_TypeDef类型)一般为该外设的所有寄存器的起始基地址&#xff0c;第二个成员Init&#xff08;xx_InitTypeDef类型&#xff09;一般为该外设的设…

高精度模板

加法 P1601 AB Problem&#xff08;高精&#xff09; #include<iostream>using namespace std; const int N 1e6 10; int a[N],b[N],c[N]; int len1,len2,lenMax; //长度要提前定义在全局&#xff0c;在函数中要使用 void add(int c[],int a[],int b[]) {for(int i0…

monorepo使用指北

|  WARN  node_modules is present. Lockfile only installation will make it out-of-date  ERR_PNPM_FETCH_404  GET https://registry.npmjs.org/common%2Fcommon: Not Found - 404 This error happened while installing a direct dependency of G:\monorepo\vue3 comm…

Java八股文——Spring「MyBatis篇」

与传统的JDBC相比&#xff0c;MyBatis的优点&#xff1f; 面试官您好&#xff0c;MyBatis相比于传统的JDBC&#xff0c;它并不是要完全颠覆JDBC&#xff0c;而是作为JDBC的一个强大的“增强框架”。它的核心价值在于&#xff0c;在保留了SQL最大灵活性的前提下&#xff0c;极大…

JavaScript基础-常用的鼠标事件

一、前言 在前端开发中&#xff0c;鼠标事件 是实现用户交互的重要手段之一。通过监听用户的点击、移动、悬停等操作&#xff0c;我们可以构建出丰富而灵活的网页交互体验。 本文将带你深入了解&#xff1a; JavaScript 中常见的鼠标事件&#xff1b;各类鼠标事件的触发时机…

windows录频软件

一.很反感有些做软件的&#xff0c;把别人开源的改个界面收费&#xff0c;所以我找了一个开源免费的。 二.准备工具 一台电脑&#xff0c; Captura:完全开源免费的录频软件。 ffmpeg&#xff1a;音频格式转换软件&#xff0c;这可是非常大名鼎鼎的工具。 三.安装Captura 网址…

python中的模块化编程:日期模块、math算术模块、random模块

内置模块&#xff08;math、random、时间&#xff09;自定义模块&#xff08;自己写的部分代码&#xff09;第三方模块&#xff08;引入的第三方代码库的模块&#xff09; math模块 import math#圆周率 print(math.pi) #自然常数 print(math.e) #圆周率的二倍 print(math.tau…

【学习笔记】Langchain基础(二)

前文&#xff1a;【学习笔记】Langchain基础 文章目录 8 [LangGraph] 实现 Building Effective Agents&#xff0c;各种 workflows 及 AgentAugmented LLMPrompt ChainingParallelizationRoutingOrchestrator-Worker (协调器-工作器)Evaluator-optimizer (Actor-Critic)Agent 8…

Java大模型开发入门 (9/15):连接外部世界(中) - 向量嵌入与向量数据库

前言 在上一篇文章中&#xff0c;我们成功地将一篇长文档加载并分割成了一系列小的文本片段&#xff08;TextSegment&#xff09;。我们现在有了一堆“知识碎片”&#xff0c;但面临一个新问题&#xff1a;计算机如何理解这些碎片的内容&#xff0c;并找出与用户问题最相关的片…

Windows下MySQL安装全流程图文教程及客户端使用指南(付整合安装包)

本教程是基于5.7版本安装&#xff0c;5.7和8.0的安装过程大差不差 安装包「windows上mysql中安装包资源」 链接&#xff1a;https://pan.quark.cn/s/de275899936d 一、安装前的准备 1.1 获取 MySQL 安装程序 官网 前往 MySQL 官方下载页面&#xff0c;下载适用于 Windows 系…

笔记 软件工程复习

第一章 软件工程学概述 1.1 软件危机&#xff08;Software Crisis&#xff09; 概念 定义&#xff1a;软件危机指在计算机软件开发与维护过程中遇到的一系列严重问题&#xff0c;源于1960年代软件复杂度激增与传统开发方法失效的矛盾。 本质&#xff1a;软件规模扩大 → 开…

GaussDB创建数据库存储

示例一&#xff1a; 下面是一个简单的GaussDB存储过程示例&#xff1a; –创建一个存储过程。 CREATE OR REPLACE PROCEDURE prc_add (param1 IN INTEGER,param2 IN OUT INTEGER ) AS BEGINparam2: param1 param2;dbe_output.print_line(result is: ||to_char(param…