행복을 담는 블로그
[TIL] 240123(화) React 입문 개인과제 : To-do list 만들기(3) / 컴포넌트 분리하기 본문
🚨 컴포넌트로 분리하기
본격적으로 코드를 작성하기에 앞서 반복되는 컴포넌트를 먼저 분리하면 더 쉽게 코드를 작성할 수 있다.
(아니 사실 과제 할 때는 마지막에 컴포넌트 분리했는데,,, 분리하다가 계속 오류가 나서 죽을 뻔 했다,,,)
개인과제 해설 보고 깔끔하게 코드를 작성하기 위해서 컴포넌트를 열심히 분리해서 다시 작성해보았다.
크게는 App 컴포넌트
> Header / TodoController
> TodoForm / TodoList
> TodoCards
이렇게 여러개의 컴포넌트로 구성하였다.
📌 component를 분리하면 꼭, import/ export를 사용하여 두 컴포넌트 사이를 연결 시켜줘야한다!!
1) App
각 구역 단위로 컴포넌트를 따로 분리하여 작성하니 App 컴포넌트의 코드가 아주 깔끔하게 가독성이 좋아졌다.
import React from "react";
import "./App.css";
import TodoHeader from "component/layout/Header";
import TodoController from "component/todo/TodoController";
const App = () => {
return (
<>
<div className="app-style">
<TodoHeader />
<TodoController />
</div>
</>
);
};
export default App;
2) Header
Header 부분은 딱히 크게 작성할 부분이 없었지만, 누가봐도 이곳은 header이다 라고 알 수 있도록, <header></header>
태그를 이용하여 작성한다.
const TodoHeader = () => {
return (
<header>
<h1 className="headerStyle">My To-Do List</h1>
</header>
);
};
export default TodoHeader;
3) TodoController
TodoController에는 세 개의 컴포넌트를 연결시켜준다.
이때, TodoList는 Working...🔥
과 Done🎉
두 부분에서 반복적으로 사용되므로, 하나의 TodoList 라는 컴포넌트를 생성하여 반복된 코드를 줄인다.
- TodoForm : input 창과 button으로 이루어진 컴포넌트
- TodoList : map 함수를 이용해 새로운 카드를 생성하고, Working과 Done의 두 부분에서 반복적으로 사용되는 컴포넌트
각각의 컴포넌트에 필요한 함수를 props로 넘겨준다.
import { useState } from "react";
import TodoForm from "./TodoForm";
import TodoList from "./TodoList";
/* 초기 기본 card 객체 생성하기 */
const todoObj = {
id: 1,
title: "리액트 공부하기",
text: "리액트 기초를 공부해봅시다.",
isDone: false,
};
const TodoController = () => {
/* 렌더링이 필요한 부분 State 생성하기 */
const [cards, setCards] = useState([todoObj]);
// input 태그 : title과 text 각각 입력 받아 state 생성
const [title, setTitle] = useState("");
const [text, setText] = useState("");
const addTitleHandler = (event) => {
setTitle(event.target.value);
};
const addTextHandler = (event) => {
setText(event.target.value);
};
/* TodoForm : card 추가하기 */
const addSubmit = (e) => {
// form 태그의 자동 새로고침 막기
e.preventDefault();
// 빈 input 추가 막기
if (!title || !text) {
return;
}
// 새로운 카드 생성하기
const newCards = {
id: cards.length + 1,
title,
text,
isDone: false,
};
setCards([...cards, newCards]);
//처음 작성한 input 창 초기화
setTitle("");
setText("");
e.target.reset();
};
/* card Delete 버튼 */
const removeCardBtn = (id) => {
const removeCards = cards.filter((card) => card.id !== id);
setCards(removeCards);
};
/* Done/Cancle 버튼 */
const updateCardBtn = (id) => {
const updatedTodos = cards.map((todo) => {
if (todo.id === id) {
return {
...todo,
isDone: !todo.isDone,
};
}
return todo;
});
setCards(updatedTodos);
};
/* TodoList 2가지 분리하여 작성 */
const workingCards = cards.filter((card) => !card.isDone);
const doneCards = cards.filter((card) => card.isDone);
return (
<main>
<TodoForm
addTitleHandler={addTitleHandler}
addTextHandler={addTextHandler}
addSubmit={addSubmit}
/>
<TodoList
subTitle="Working...🔥"
cards={workingCards}
removeCardBtn={removeCardBtn}
updateCardBtn={updateCardBtn}
/>
<TodoList
subTitle="Done🎉"
cards={doneCards}
removeCardBtn={removeCardBtn}
updateCardBtn={updateCardBtn}
/>
</main>
);
};
export default TodoController;
4) TodoForm
TodoForm 컴포넌트에는 title과 content를 입력할 수 있는 input 창 2개와 새로운 카드를 추가할 수 있는 button으로 이루어져 있다.
<form></form>
태그를 사용하여 keyboard에서 키를 눌렀을 때 submit event가 발생한다.- 필요한 key와 함수를 props로 받는다.
const TodoForm = ({ title, text, addTitleHandler, addTextHandler, addSubmit }) => {
return (
<form className="inputStyle" onSubmit={addSubmit}>
Title <input className="titleClass" value={title} onChange={addTitleHandler} />
Content <input className="textClass" value={text} onChange={addTextHandler} />
<button id="addBtn" type="submit" className="btn btn-outline-dark">
Add
</button>
</form>
);
};
export default TodoForm;
5) TodoList
TodoList는 TodoController에서 두 번 사용되는 컴포넌트이다.
- cards를 map 함수를 이용하여 새로운 배열로 만들어 새로운 list를 구성한다.
- 각각의 cards는 새로운 TodoCards를 이용하여 생성한다.
import TodoCards from "./TodoCards";
const TodoList = ({ cards, subTitle, removeCardBtn, updateCardBtn }) => {
return (
<section className="cardSection">
<h2>{subTitle}</h2>
<ul className="card-container">
{cards.map(function (item) {
return (
<TodoCards
key={item.id}
item={item}
removeCardBtn={removeCardBtn}
updateCardBtn={updateCardBtn}
/>
);
})}
</ul>
</section>
);
};
export default TodoList;
6) TodoCards
생성한 card의 id, title, text, isDone
을 props로 넘겨 받아 각각의 필요한 위치에서 받아서 card를 생성한다.
- Done과 Cancle의 버튼의 경우 삼항 연산자를 사용하여 버튼의 이름을 생성한다.
- isDone이 false이면 Done으로, isDone이 true이면 Cancle로 버튼을 생성한다.
const TodoCards = ({ item, removeCardBtn, updateCardBtn }) => {
const { id, title, text, isDone } = item;
return (
<div key={id} className="cardList">
<h2>{title}</h2>
<p>{text}</p>
<button
id="removeBtn"
type="button"
className="btn btn-danger"
onClick={() => removeCardBtn(id)}
>
Delete
</button>
<button
id="completeBtn"
type="button"
className="btn btn-success"
onClick={() => updateCardBtn(id)}
>
{isDone ? "Cancle" : "Done"}
</button>
</div>
);
};
export default TodoCards;
'TIL' 카테고리의 다른 글
[TIL / 프로그래머스] 240125(목) 내적 / array.reduce( ) - currentIndex 사용하기 (1) | 2024.01.25 |
---|---|
[TIL] 240124(수) React 숙련주차 시작 / map( ), filter( ) 메소드 복습 (0) | 2024.01.24 |
[TIL] 240123(화) React 입문 개인과제 : To-do list 만들기(2) / Todo 완료/취소하기 (0) | 2024.01.24 |
[TIL] 240123(화) React 입문 개인과제 : To-do list 만들기(1) (0) | 2024.01.23 |
[TIL] 240119(금) React / 간단한 숫자 카운터 앱 만들기 (0) | 2024.01.19 |