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>);
}
代碼解釋:
{...}
: 我們在JSX中打開了一個JavaScript代碼塊。fruits.map(...)
: 我們調用了fruits
數組的map
方法。(fruit, index) => { ... }
: 這是一個箭頭函數,它會被map
方法在遍歷數組時,對每個元素都調用一次。fruit
: 代表當前正在被遍歷的元素(比如第一次是 ‘蘋果 🍎’)。index
: 代表當前元素的索引(從0開始)。
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
的兩個重要原則:
key
在兄弟元素之間必須是唯一的。 就像一個班級里,每個學生的學號都不能重復。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界面了。核心知識點回顧:
- 核心工具: JavaScript的**
.map()
**數組方法。 - 核心思想: 將數據數組映射為UI元素數組。
key
屬性: 它是React識別列表項的“身份證”,在兄弟節點間必須是唯一且穩定的。- 最佳實踐: 優先使用數據本身提供的唯一ID作為
key
。
我們已經能根據數據批量生成UI了。但有時候,我們并不想顯示所有內容,而是想根據某些條件來決定某個UI部分是否應該顯示。例如,用戶登錄后才顯示“歡迎信息”,或者數據正在加載時顯示“加載中…”。
在下一篇文章 《React條件渲染:如何根據不同條件顯示或隱藏一個組件?》 中,我們將學習如何控制UI的顯示和隱藏邏輯,讓我們的應用更加智能。我們下期再會!