iT邦幫忙

2022 iThome 鐵人賽

DAY 8
0
Modern Web

你 React 了嗎? 30 天解鎖 React 技能系列 第 8

[DAY 8] React 列表渲染,將陣列、物件渲染成元素

  • 分享至 

  • xImage
  •  

[情境任務]

小當家:我把餐廳大致上的料理都開發出來囉!名單都整理好了,直接列上去就行

解師傅:太好了~哇!這菜色有點多呢!一個一個列好像太花時間了…不知道能不能一次把這些通通放到菜單上呢?老闆你有什麼想法嗎?

用複製組件的方法雖然不是不行,但我們想要更有效率且好維護的方法/images/emoticon/emoticon13.gif


cover

列表渲染

當資料開始多時,將每個元件都複製、塞 props,這並不是一個好維護的作法,
明明是做同一件事卻看起來很冗長

<ul>
    <List name="蘆筍沙拉" price={100} />
    <List name="辣炒空心菜" price={120} />
    <List name="雞蛋豆腐" price={150}/>
    <List name="鳳梨蝦球" price={300}/>
    <List name="糖醋雞丁" price={200}/>
    <List name="砂鍋魚頭" price={500}/>
    <List name="竹筍炒肉絲" price={150}/>
    <List name="梨山高麗菜" price={120}/>
</ul>

這結構其實都一樣,我們可以將資料模組化,再從一個集合中把資料渲染到畫面,像 Vue、Angular 會有自定義渲染列表的模版,而 React 並沒有列表模版,大多是使用 JavaScript 本身的語法 map 產生,以下列出陣列與物件的渲染方式

◆ 陣列渲染成元素

function App() {
  const chef = [
    { name: "小當家" }, 
    { name: "解師傅" }, 
    { name: "雷恩" }
  ];
  
  return (
    <ul>
      {chef.map((item, index) => (
        <li key={item.name}>
          {index + 1}. {item.name}
        </li>
      ))}
    </ul>
  );
}

export default App;

資料為一個陣列,要重複渲染的地方用大括弧 {} 包住,使用 JavaScript 的陣列語法 map 將每個 item 渲染出來,map 的第二個參數為索引值 index

codesandbox 程式碼範例

map array

除了陣列,物件也可以渲染

◆ 物件渲染成元素

function App() {
  const chef = {
    name: "小當家",
    age: 13,
    height: 150
  };
  
  return (
    <ul>
      {Object.keys(chef).map((key) => {
        const value = chef[key];
        return (
          <li key={value}>
            {key}: {value}
          </li>
        );
      })}
    </ul>
  );
}

export default App;

物件使用 Object.keys 先把物件屬性變成陣列,再使用 map 渲染

物件渲染出來的結果順序不一定相同,如果要照資料排序須將資料改為陣列

codesandbox 程式碼範例

map object

你可能會發現,不管是陣列或物件,為什麼渲染列表第一個元素都有 key 屬性?/images/emoticon/emoticon19.gif

key 必須是唯一值

不管是陣列或物件,渲染出來的第一個元素需要帶入 key 屬性,key 是用來辨別元素的改變或增減

如陣列改變,React 會透過 key 去比較新舊元素有無變更,只改變有變更的元素,才不會整個列表再被重新渲染,影響效能

如果你忘了加 key,在 console 也會跳出錯誤,提醒你要加 key

key

◆ 不建議使用索引作為 key,尤其如果項目的順序會改變的話,這會對效能產生不好的影響,也可能會讓 component 資料產生問題,最好的方法還是加上唯一值,通常可以加上 id


[任務解題]
利用陣列渲染出 menu,渲染 component,並帶入 item 的 props,記得也要加上 key 哦!

import List from "./components/List";

function App() {
  const menu = [
    { name: "蘆筍沙拉", price: 100 },
    { name: "辣炒空心菜", price: 120 },
    { name: "雞蛋豆腐", price: 150 },
    { name: "鳳梨蝦球", price: 300 },
    { name: "糖醋雞丁", price: 200 },
    { name: "砂鍋魚頭", price: 500 },
    { name: "竹筍炒肉絲", price: 150 },
    { name: "梨山高麗菜", price: 120 },
    { name: "五更腸旺", price: 250 },
    { name: "客家小炒", price: 250 },
    { name: "三杯杏鮑菇", price: 180 }
  ];

  return (
    <div className="App">
      <h1>React 熱炒店</h1>
      <ul>
        {menu.map((item, index) => (
          <List
            key={item.name}
            name={item.name}
            price={item.price}
            index={index}
          ></List>
        ))}
      </ul>
    </div>
  );
}

export default App;

餐廳的菜單列表就這樣被渲染出來囉!/images/emoticon/emoticon07.gif
有新的菜色或需要調整時,直接更改 menu 陣列就可以了!

codesandbox 程式碼範例

menu

結語

學會渲染列表就可以做很多事了,看起來簡短很多,重要的是好維護,當需要修改資料時,不用去找 component 的 props,直接統一在資料模組管理就好了!


本文將同步更新至我的部落格
Lala 的前端大補帖



上一篇
[DAY 7] props 上面傳下來的屬性
下一篇
[DAY 9] 事件處理 - 我這人很簡單,有打卡就給讚
系列文
你 React 了嗎? 30 天解鎖 React 技能30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言