사고쳤어요
[React / ts] Task App 만들기 - ③ ActionButton 만들기 본문

"새로운 일 등록" 버튼과 "새로운 리스트 등록" 버튼을 눌렀을 때 각 기능을 수행할 수 있도록 구현해보자.
// ActionButton.tsx
import React, { useState } from "react";
import { IoIosAdd } from "react-icons/io";
import DropDownForm from "../DropDownForm/DropDownForm";
import { listButton, taskButton } from "./ActionButton.css";
type TActionButtonProps = {
boardId: string;
listId: string;
list?: boolean;
};
const ActionButton: React.FC<TActionButtonProps> = ({
boardId,
listId,
list,
}) => {
const [isFormOpen, setIsFormOpen] = useState(false);
const buttonText = list ? "새로운 리스트 등록" : "새로운 일 등록";
return isFormOpen ? (
<DropDownForm
setIsFormOpen={setIsFormOpen}
list={list ? true : false}
boardId={boardId}
listId={listId}
/>
) : (
<div
className={list ? listButton : taskButton}
onClick={() => setIsFormOpen(true)}
>
<IoIosAdd />
<p>{buttonText}</p>
</div>
);
};
export default ActionButton;
ActionButton은 "새로운 리스트 등록", "새로운 일 등록" 두 가지의 경우를 모두 처리한다.
따라서 list를 props로 전달받아 이가 true일 때를 리스트, false일 때는 일을 추가한다.
ActionButton은 기본적으로 "새로운 ... 등록"을 보여주고 있다가, 만약 이를 클릭할 경우
텍스트를 입력할 수 있는 input과 추가 버튼이 포함된 DropDownForm을 보여주도록 하였다.
// DropDownForm.tsx
import React, { ChangeEvent, useState } from "react";
import { FiX } from "react-icons/fi";
import { useTypedDispatch } from "../../hooks/redux";
import { v4 } from "uuid";
import { addList, addTask } from "../../store/slices/boardsSlice";
import { addLog } from "../../store/slices/loggerSlice";
import {
button,
buttons,
input,
listForm,
taskForm,
close,
} from "./DropDownForm.css";
type TDropDownFormProps = {
boardId: string;
listId: string;
setIsFormOpen: React.Dispatch<React.SetStateAction<boolean>>;
list?: boolean;
};
const DropDownForm: React.FC<TDropDownFormProps> = ({
boardId,
listId,
setIsFormOpen,
list,
}) => {
const dispatch = useTypedDispatch();
const [text, setText] = useState("");
const handleTextChange = (e: ChangeEvent<HTMLTextAreaElement>) => {
setText(e.target.value);
};
const formPlaceHolder = list
? "리스트의 제목을 입력하세요"
: "일의 제목을 입력하세요";
const buttonTitle = list ? "리스트 추가하기" : "일 추가하기";
const handleButtonClick = () => {
if (text) {
if (list) {
dispatch(
addList({
boardId,
list: { listId: v4(), listName: text, tasks: [] },
})
);
dispatch(
addLog({
logId: v4(),
logMessage: `리스트 생성하기: ${text}`,
logAuthor: "User",
logTimestamp: Date.now().toString(),
})
);
} else {
dispatch(
addTask({
boardId,
listId,
task: {
taskId: v4(),
taskName: text,
taskDescription: "",
taskOwner: "User",
},
})
);
dispatch(
addLog({
logId: v4(),
logMessage: `일 생성하기 ${text}`,
logAuthor: "User",
logTimestamp: Date.now().toString(),
})
);
}
}
};
return (
<div className={list ? listForm : taskForm}>
<textarea
className={input}
autoFocus
placeholder={formPlaceHolder}
onChange={(e) => {
handleTextChange(e);
}}
onBlur={() => setIsFormOpen(false)}
/>
<div className={buttons}>
<button className={button} onMouseDown={handleButtonClick}>
{buttonTitle}
</button>
<FiX className={close} />
</div>
</div>
);
};
export default DropDownForm;
본격적으로 list 추가하기 기능과 task 추가하기 기능을 구현하는 단계이다.
dispatch를 활용하여 addList와 addTask를 받아와 실행해주면 된다.
// boardsSlice.ts
addList: (state, { payload }: PayloadAction<TAddListAction>) => {
state.boardArray.map((board) =>
board.boardId === payload.boardId
? { ...board, lists: board.lists.push(payload.list) }
: board
);
},
addTask: (state, { payload }: PayloadAction<TAddTaskAction>) => {
state.boardArray.map((board) =>
board.boardId === payload.boardId
? {
...board,
list: board.lists.map((list) =>
list.listId === payload.listId
? { ...list, tasks: list.tasks.push(payload.task) }
: list
),
}
: board
);
},
addList와 addTask를 처리하는 부분이다.
board -> list -> task의 계층 구조로 이루어져 있다는 것을 생각하면 어렵지 않게 구현할 수 있다.

'웹 풀스택' 카테고리의 다른 글
| [React / ts] Task App 만들기 - ⑤ Logger Modal 만들기 (0) | 2025.04.17 |
|---|---|
| [React / ts] Task App 만들기 - ④ Modal 만들기 (0) | 2025.04.17 |
| [React / ts] Task App 만들기 - ② list, task 만들기 (0) | 2025.04.15 |
| [React / ts] Task App 만들기 - ① board 만들기 (0) | 2025.04.15 |
| [React] Redux 사용하기 (1) | 2025.04.14 |