2-12 JSX 中迴圈的使用
在上個單元中我們把程式碼重構之後,現在我們要來說明如何在 JSX 中使用迴圈,以達到快速重複使用多個元件的方式。
還記得我們曾經說過,使用元件(component)的好處在於可以快速地重複使用已經寫好的元件,而且每個元件的狀態都是獨立的,也就是說,你不會因為點了「第一個」計數器的向上按鈕,使得剩下其他計數器的數字也都加一,而是只有「第一個」計數器的數字會改變而已。
假設今天我們想要在畫面上產生多個計數器,可以來看看要怎麼做。
#
直接使用多個 Component其中最簡單直觀的方式,就是在 JSX 中去直接帶入多個 Component,這裡也就是指 <Counter />
這個元件。因為 React 中每個元件其實都是各自獨立的,因此當我們想要一次產出非常多的計數器時,只需要寫很多次 <Counter />
,讓我們先產生 7 個計數器就好,同時透過行內樣式的方式,在最外層的 <div>
加上 style
屬性來進行簡單的樣式調整,像下面這樣:
caution
💡 提醒:由於一個 JSX 元素最多只能有一個最外層的元素,因此當我們要轉譯很多的 <Counter />
時,為了要讓外層只有一個元素,可以加上一個額外的 <div>
把所有 <Counter />
包起來。
除了在最外層的 <div>
元素上透過 style
屬性來簡單進行樣式的調整,也稍微修改一下 <Counter />
元件的 <div class="container">
這個元素的樣式,加上 minWidth
來讓各個計數器之間保有一定的間距:
現在我們的畫面應該會像這樣子:
實際操作時你會發現到,每個元件間的資料狀態都是各自獨立的,並不會互相干擾。你可以想像如果沒有 React,使用原生的 JavaScript 來做的話,會需要選取出多少個元素和綁定多少個事件呢?
#
使用迴圈重複產生多個計數器你可能會說,既然 JSX 本質上都是 JavaScript 了,難道還得要手動複製貼上 <Counter />
,不能用迴圈的方式,看要幾個有幾個嗎?
當然是可以的!既然 JSX 本質上就是 JavaScript ,那麼你當然可以使用 JavaScript 學到的方式來重複產生多個計數器。當在 JavaScript 中要重複執行某一個內容或動作時,很直覺的會想到可以用 for 迴圈
。首先你可能會很直覺的這麼寫:
和我們在條件轉譯中提到的情況一樣,這麼做程式並沒有辦法正確執行,原因在於 for 迴圈
本身是個 statements 而非 expressions,執行的時候並不會有回傳值,因此不能直接放到 JSX 中的 {}
內去執行。那麼實際上可以怎麼做呢?
在 React 中,當我們要做重複轉譯多個元件時,最常使用到的是透過陣列的 map
方法,因為 map
這個方法會有回傳值,所以可以直接在 JSX 中使用。
實際的做法會像這樣:
- 先產生一個帶有多個元素的陣列
- 在 JSX 中將這個陣列使用
map
方法,並且每次都回傳<Counter />
元素
#
產生帶有多個元素的陣列在 JavaScript 有許多不同的方式都可以產生帶有多個元素的陣列,這裡我們使用 Array.from({ length: n })
這個方法來產生帶有 n 個 undefined
的陣列,像是這樣:
#
透過陣列的 map 方法來執行迴圈接下來,就可以在 JSX 中透過在 {}
內使用 counters.map(() => <Counter />)
的方式,就可以產生帶有多個 <Counter />
的陣列,像是這樣:
這樣寫的意思其實就等同於:
info
💡 Tips:map 回傳的內容除了可以是 React 元件外,更常見的會是 DOM 元素,像是透過迴圈重複產生多個 <li>
。
這時候我們就會看到畫面瞬間產生了 8 個計數器,是不是非常快速方便呢!然而,若我們打開瀏覽器的 console 視窗,會看到有錯誤提示產生:
意思是要提示我們最好把每個透過迴圈重複產生的元件加上 key 這個屬性,而每個 key 的值都應該要是唯一不重複的,如此 React 才會比較清楚迴圈中有哪些項目是被修改或操作過的,一般來說,如果我們有多個使用者的資料需要使用迴圈呈現時,可以直接使用每個使用者的 id 當作 key 值,因為使用者的 id 一般來說是唯一不會重複的,例如:
但因為在我們的計數器中並沒有唯一的 id 存在,在沒有其他選擇的情況下,我們可以把陣列的 index 當成 key 帶入,像是這樣:
當我們把 key 補上之後,錯誤提示就不會出現了。
tip
💡 補充:React 並不建議我們直接拿陣列的 index 來當作 key 的值帶入,特別是在這些元素的順序有可能會有改變的情況下,對於效能會有不好的影響;但這裡因為主要是示範用途,並且只是單純用來呈現資料,沒有要操作或修改這些元素,因此對於效能的影響不大。
#
換你了:透過迴圈產生多個計數器吧在這裡我們提到了如何在 JSX 中搭配陣列的 map 方法來快速產生多個 React 元件,要提醒的是在 map 中回傳的內容,除了可以是 React 元件之外,也可以是 HTML 元素,像是透過 <li>
來產生一系列的清單等等。
現在,請你試著練習看看,如何透過 map 的方式一次產生多個計數器在畫面中吧!過程中如果有任何不清楚的地方,都可以從下方連結中檢視實作的程式碼,或於 Github 專案說明頁點擊連結「JSX 中迴圈的使用」: