我們要將 useReducer 中看板的 state 顯示出來。首先在 src/components 資料夾中新增 Card 資料夾,然後在 Card 資料夾底下新增名稱為 Card.js 的檔案以及 Card.module.scss 的樣式檔案:
import React from "react";
import styles from "./Card.module.scss";
const Card = props => {
return (
<div className={styles.card}>
{props.value}
</div>
);
};
export default Card;
.card {
border-radius: 4px;
background-color: white;
box-shadow: 1px 1px 1px gray;
margin: 4px 0;
padding: 8px;
cursor: pointer;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
其中先準備好從 props 中取得卡片的內容 value 並且顯示出來。
建好 Card 元件之後,我們就可以在 Board 元件中來使用它,並且傳入看卡片內容:
import React from "react";
import styles from "./Board.module.scss";
// 引用 Card 元件
import Card from "../Card/Card";
const Board = props => {
const [isEditingName, setIsEditingName] = React.useState(false);
const [isAddingCard, setIsAddingCard] = React.useState(false);
const [inputValue, setInputValue] = React.useState("");
return (
<div className={styles.board}>
<button
className={styles.closeButton}
onClick={() => {
props.dispatch({
type: "REMOVE_BOARD",
payload: {
boardId: props.id
}
});
}}
>
x
</button>
{isEditingName ? (
<input
autoFocus
value={props.name}
className={styles.editNameInput}
onChange={e => {
dispatch({
type: "CHANGE_BOARD_NAME",
payload: {
boardId: props.id,
boardName: e.target.value
}
});
}}
onKeyPress={e => {
if (e.key === "Enter") {
setIsEditingName(false);
}
}}
/>
) : (
<h2
className={styles.name}
onClick={() => setIsEditingName(true)}
>
{props.name}
</h2>
)}
{/* 從 props 取得 cardIds 和 cardsById 並且使用 Card 元件 */}
{props.cardIds.map((id, index) => (
<Card
key={id}
value={props.cardsById[id]}
))}
{isAddingCard ? (
<input
className={styles.addCardInput}
autoFocus
value={inputValue}
onChange={e => setInputValue(e.target.value)}
onKeyPress={e => {
if (e.key === "Enter") {
dispatch({
type: "ADD_CARD",
payload: {
boardId: props.id,
cardValue: inputValue.trim()
}
});
setInputValue("");
setIsAddingCard(false);
}
}}
/>
) : (
<button
className={styles.addCardButton}
onClick={() => setIsAddingCard(true)}
>
+新增卡片
</button>
)}
</div>
);
};
在 App 元件中使用 Board 元件要多傳入 cardIds 和 cardsById 兩個 props:
<Board
key={id}
name={state.boards.byId[id].name}
// 多傳入 cardIds 和 cardsById
cardIds={state.boards.byId[id].cardIds}
cardsById={state.cards.byId}
/>
礙於篇幅受限,製作簡易專案管理網站的進度就到這邊,剩下的功能:改變看板順序、改變卡片順序、刪除卡片等需要結合 HTML Drag & Drop API,就留給讀者們自行到 CodeSandbox 摸索囉!