iT邦幫忙

2023 iThome 鐵人賽

DAY 26
0
Modern Web

30 days of React 系列 第 26

Day 26 - React 基礎實作練習:追加購物清單

  • 分享至 

  • xImage
  •  

今天要來製作購物清單,透過這個練習我們可以複習 Lifting State Up 的觀念。先來看目前的程式碼:

  • App.js
import React from "react";

import AddNewItemForm from "./AddNewItemForm";

function App() {
  return (
    <div className="wrapper">
      <div className="list-wrapper">
        <ol className="shopping-list">
          <li>Avocados</li>
          <li>Broccoli</li>
          <li>Carrots</li>
        </ol>
      </div>
      <AddNewItemForm />
    </div>
  );
}

export default App;
  • AddNewItemForm.js
import React from "react";

function AddNewItemForm() {
  return (
    <div className="new-list-item-form">
      <form>
        <label htmlFor="new-list-form-input">New item:</label>

        <div className="row">
          <input id="new-list-form-input" type="text" />
          <button>Add</button>
        </div>
      </form>
    </div>
  );
}

export default AddNewItemForm;

畫面目前是這樣:

現狀分析

  • 現有的 List 生成不是自動生成的
  • 沒有狀態變數的設定
  • Input 裡面沒有資料綁定

操作步驟

Step 1: 設定狀態變數

在 App.js 檔案中設定狀態變數,先將初始值設定為一個 empty array。

const [items, setItems] = React.useState([]);

先以假想的資料來做測試,將裡頭放置資料物件:

const [items, setItems] = React.useState([
  { label: "kiwi", id: 123 },
  { label: "banana", id: 456 },
  { label: "mango", id: 789 },
]);

Step 2: 在 JSX 中設定動態生成

{
  items.map(({ id, label }) => <li key={id}>{label}</li>);
}

透過解構賦值的方法,可以在<li>元素當中直接使用{id}{label}

現在我們可以在畫面中看到測試的資料了,這樣已經確定動態生成的功能正常運作。

Step 3:編寫追加 item 的 function

接著要來編寫讓清單能夠追加項目的 function,我們在 App 元件當中創建並將這個 function 命名為handleAddItem

function handleAddItem(label) {
  const newItem = {
    label,
    id: Math.random(),
  };

  const nextItems = [...items, newItem];
  setItems(nextItems);
}

在這個 function 當中要處理的事情以三件,(1) 先將新 item 的組織宣告為newItem 變數,透過 id:Math.random() 來隨機產生 id,用於 JSX 所需的 key (2) 接著將 nextItems,也就是下一次渲染的清單也宣告為變數,透過展開當前的 items 並加上 newItem 來完成下一次渲染的邏輯。(3)使用-setItems() 觸發渲染。

Step 4: 傳遞 handleAddItem 至 AddNewItemForm 元件

為了讓 handleAddItem function 可以在 AddNewItemForm 當中可以使用,必須透過 props 傳遞。

<AddNewItemForm handleAddItem={handleAddItem} />

也需要在子元件 AddNewItemForm 當中來設定 props 的傳入。

function AddNewItemForm({handleAddItem})

Step 5: 預防事件預設表現並呼叫 function

來到 AddNewItemForm.js 的檔案中繼續編輯。先在 form 元素上添加onSubmit attribute 並設置預防事件預設表現的 function。同時也呼叫handleAddItem function。。

     <form
        onSubmit={(event) => {
          event.preventDefault();
          handleAddItem()
        }}
      >

Step 6:設置 label 的狀態變數並綁定資料

在元件內設置狀態變數以利後續的追加項目,並在 JSX 當中綁定資料。

  • 狀態變數
const [label, setlabel] = React.useState("");
  • 綁定資料
<input
  id="new-list-form-input"
  type="text"
  value={label}
  onChange={(event) => {
    setLabel(event.target.value);
  }}
/>

添加valueonChange ,做法就跟我們這二天複習的操作的一樣。

這樣我們的 shopping list 大致就完成了

當我在輸入欄位輸入「cup ramen」,項目即順利被添加上去了。

Step 7: 清空輸入框

這邊的小問題是,當我們輸入完輸入匡的內容並沒有被清空,所以當按下下一個 enter 鍵,資料就會重複被送出,像這樣:

這個問題可以透過追加 setLabel 來解決:

    <form
        onSubmit={(event) => {
          event.preventDefault();

          handleAddItem(label);

          setLabel('')
        }}
      >

這樣即可追加完又將輸入匡渲染為空的 string。

Step 8: 刪去測試資料

將一開始放置測試資料還原為空的 array

const [items, setItems] = React.useState([]);

這樣即完成了。

參考資料

  • The Joy of React by Josh W Comeau - Lifting State UP (exercises)

上一篇
Day 25 - React 基礎實作練習:下拉式選單
下一篇
Day 27 - React Ref 實作練習
系列文
30 days of React 30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言