今日文章目綠
- 前言
- 實作需求
- 過程紀錄
- 參考資料
昨天講到component
零組件組裝的方法,但沒有提到管線怎麼安排。今天來談談component
資料傳遞的方法。
規劃流程是這樣:使用者新增分類項目,個別分類項目下有獨立的代辦清單。
問題來了,我在分類清單拿到:使用者輸入分類的state
,要怎麼傳給代辦清單?
A: 之前我們提到component
擁有一般function的功能,我們可以在呼叫函式時,把資料用參數的方式傳遞,也就是React提到的props。
props
本身的唯讀性質,不能直接修改props
,以確保資料狀態傳遞過程不會有任何改變。
規劃我的資料流傳遞方向,拆成四大component
:
toDoPage(網頁)、MainLayout(靜態UI)、CategoryList(分類清單)、ToDoList(代辦清單)。
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>
</>
);
}