리팩토링이란 건... 참으로 어렵다...
태그를 명확하게 구분하기 위해 기존의 <div>
대신 <header>
, <main>
, <section>
등을 사용함
<div>
<!-- 헤더 -->
<header></header>
<!-- 메인 페이지 -->
<main>
<!-- Todo 추가 컴포넌트 -->
<form></form>
<!-- Todo 출력 컴포넌트 -->
<div>
<!-- 진행 중인 Todo List 출력 컴포넌트 -->
<section></section>
<!-- 진행 완료한 Todo List 출력 컴포넌트 -->
<section></section>
</div>
</main>
</div>
기존의 id: todoList.length + 1
방식은 id가 중복될 위험이 존재하기 때문에,
명확한 key 구분을 위해 uuid (Universally Unique Identifier)
를 사용함
// AS-IS
const newTodo = {
id: todoList.length + 1,
title: todoTitle
content: todoContent
isDone: false,
}
// TO-BE
import { v4 as idv4 } from "uuid";
const newTodo = {
id: idv4(),
title: todoTitie,
content: todoContent,
isDone: false,
}
<form>
태그를 사용하여 submit을 활용함
<!-- AS-IS -->
<div>
<div className="todo-info">
<!-- 중략 -->
</div>
<button onClick={addTodoHandler}>추가하기</button>
</div>
<!-- TO-BE -->
<form onSubmit={addTodoHandler}>
<div className="todo-info">
<!-- 중략 -->
</div>
<button type="submit">추가하기</button>
</form>
입력 창에 값을 입력하지 않은 경우 alert 출력
const addTodoHandler = (e) => {
e.preventDefault();
if (!todoTitle || !todoContent) {
alert("빈 값이 존재합니다. 값을 입력해주세요.");
return;
}
// 이하 생략
}
Todo의 완료 여부를 판단하는 isDone 속성에 따라 <section>
을 다르게 출력하도록 설정함
// ShowTodoList.jsx
const ShowToDoList = (...) => {
return (
<>
// isDone: false
<TodoList ... checkDone={false} />
// isDone: true
<TodoList ... checkDone={true} />
</>
);
}
// TodoList.jsx
const TodoList = (...) => {
return (
<section>
<h2>{!checkDone ? "Working" : "Done"}</h2>
<div>
{todoList
.filter((todo) => todo.isDone === checkDone)
.map((todo) => {
return (
// 이하 생략
);
)}
}
</div>
</section>
);
}
[삭제]
버튼과 [완료]/[완료취소]
버튼을 별도의 컴포넌트로 분리함
// TodoList.jsx
return (
// 생략
<TodoItemButtonController ... />
);
// TodoItemButtonController.jsx
const TodoItemButtonController = (...) => {
// [삭제] 버튼 Handler
const deleteTodoHandler = () => {...}
// [완료]/[완료취소] 버튼 Handler
const editDoneHandler = () => {...}
return (
<>
<button onClick={deleteTodoHandler}>삭제하기</button>
<button onClick={editDoneHandler}>
{!checkDone ? "완료" : "완료취소"}
</button>
</>
);
}
[삭제]
/[상태 변경]
을 수행할지 확인한 뒤에 동작함
const deleteTodoHandler = () => {
const checkDeleteTodo = window.confirm("정말로 삭제하시겠습니까?");
if (checkDeleteTodo) {
// 삭제 작업
}
};
const editDoneHandler = () => {
const checkEditDone = window.confirm("정말로 상태를 변경하시겠습니까?");
if (checkEditDone) {
// 상태 변경 작업
}
};
나름대로 리팩토링을 괜찮게 수행했다고 생각했다.
하지만 간과하고 있는 것이 있었다.
컴포넌트를 완전하게 분리하려면 jsx 파일 뿐만 아니라 CSS 파일도 리팩토링을 진행했어야 한다는 것이다.
재사용을 목적에 두면 좀 더 나은 리팩토링을 수행해볼 수 있을 것 같다.
리팩토링이란 건 참으로 어려운 것 같다...