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
繁體地址,請注明出處:http://hk.pswp.cn/diannao/87126.shtml
英文地址,請注明出處:http://en.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…