iT邦幫忙

2021 iThome 鐵人賽

DAY 25
0
自我挑戰組

30天CSS、JS、React打造專案零組件系列 第 25

DAY25 - [React hook] props

  • 分享至 

  • xImage
  •  

今日文章目綠

  • 前言
  • 實作需求
  • 過程紀錄
  • 參考資料

昨天講到component零組件組裝的方法,但沒有提到管線怎麼安排。今天來談談component資料傳遞的方法。

規劃流程是這樣:使用者新增分類項目,個別分類項目下有獨立的代辦清單。

針對不同用途的toDoList

問題來了,我在分類清單拿到:使用者輸入分類的state,要怎麼傳給代辦清單?

A: 之前我們提到component擁有一般function的功能,我們可以在呼叫函式時,把資料用參數的方式傳遞,也就是React提到的props

props 本身的唯讀性質,不能直接修改props,以確保資料狀態傳遞過程不會有任何改變。

規劃我的資料流傳遞方向,拆成四大component
toDoPage(網頁)、MainLayout(靜態UI)、CategoryList(分類清單)、ToDoList(代辦清單)。

這裡要提到React特性:向下資料流

  • 從下圖可以看到,我希望 component CategoryList、ToDoList 共享資料,就必須要從兩者共同父層傳資料下來。
    規劃我的資料流傳遞方向:

實際來實作看看:
(一) toDoPage

// 引入需要的零組件:
import React, { useState } from 'react';
import MainLayout from '../../layout/mainLayout';
import CategoryList from './category';
import ToDoList from './toDoList';

// 建立component:
export default function ToDoPage() {

  // 存取 state:
  const [categoryValue, setCategoryValue] = useState('');
  const [categoryData, setCategoryData] = useState([]);

  const UNFINISHED = 'unfinished';
  const [toDoValue, setToDoValue] = useState('');
  const [toDoData, setToDoData] = useState([]);
  
  
  // 操作邏輯
  const handleSubmit = () => {
    if (categoryValue) {
      const newItemData = {
        categoryId: Date.now(),
        category: categoryValue,
        listData: [],
      };
      setCategoryData([...categoryData, newItemData]);
      setCategoryValue('');
    } 
  };

  const handleAddListItem = () => {
    if (toDoValue) {
      const newValue = {
        id: Date.now(),
        value: toDoValue,
        status: UNFINISHED,
        spendTime: 0,
      };
      setToDoData([...toDoData, newValue]);
      setToDoValue('');
    }
  };

  return ( // 回傳 React element
    <MainLayout
      menu={( // 將共用資料傳入子元件
        <CategoryList
          handleSubmit={handleSubmit}
          categoryValue={categoryValue}
          setCategoryValue={setCategoryValue}
          categoryData={categoryData}
        />
      )}
      content={( // 將共用資料傳入子元件
        <ToDoList
          handleAddListItem={handleAddListItem}
          toDoValue={toDoValue}
          setToDoValue={setToDoValue}
          toDoData={toDoData}
        />
      )}
    />
  );
}

(二)CategoryList

import React from 'react';
import {
  Menu, Space, Button, Input,
} from 'antd';

export default function CategoryList(props) {

  // 將接收的資料由參數傳入,傳入的props是一物件,可以透過物件解構取得資料
  const { 
    handleSubmit,
    categoryValue,
    setCategoryValue,
    categoryData,
  } = props;

  return (  // 取得的資料,就可以在元件內使用
    <>
      <Menu
        theme="dark"
        mode="inline"
        style={{ height: '100%', borderRight: 0 }}
      >
        {categoryData.map((item) => (
          <Menu.Item key={item.categoryId}>{item.category}</Menu.Item>
        ))}
        <Space>
          <Input
            value={categoryValue}
            onChange={(e) => setCategoryValue(e.target.value)}
          />
          <Button type="primary" onClick={handleSubmit}>+</Button>
        </Space>
      </Menu>
    </>
  );
}

  • 顯示效果:
    顯示效果

參考資料


上一篇
DAY24 - [React hook] component 零組件
下一篇
DAY26 - [React] 登入登出 router
系列文
30天CSS、JS、React打造專案零組件30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言