[To-Do List] 제작 프로젝트 #2 - 코드 리팩토링

G_NooN·2024년 1월 25일
0

프로젝트

목록 보기
8/13

리팩토링이란 건... 참으로 어렵다...

공통 리팩토링

컴포넌트 분리

  1. 레이아웃(layout)
  • Header.jsx (헤더)
  • MainPage.jsx (메인 페이지)
  1. 메인 페이지 내부
  • AddTodoForm.jsx (Todo 추가 컴포넌트)
  • ShowTodoList.jsx (전체 Todo 출력 컴포넌트)
  1. 전체 Todo 출력 컴포넌트 내부
  • TodoList.jsx (진행상태에 따른 각 Todo List 출력 컴포넌트)

시맨틱 태그 사용

태그를 명확하게 구분하기 위해 기존의 <div> 대신 <header>, <main>, <section> 등을 사용함

<div>
  <!-- 헤더 -->
  <header></header>
  <!-- 메인 페이지 -->
  <main>
  	<!-- Todo 추가 컴포넌트 -->
    <form></form>
    <!-- Todo 출력 컴포넌트 -->
    <div>
      <!-- 진행 중인 Todo List 출력 컴포넌트 -->
      <section></section>
      <!-- 진행 완료한 Todo List 출력 컴포넌트 -->
      <section></section>
    </div>
  </main>
</div>

uuid 사용

기존의 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,
}

Todo 추가 컴포넌트

form 태그 사용

<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 출력 컴포넌트

삼항 연산자를 사용하여 반복되는 컴포넌트 처리

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 파일도 리팩토링을 진행했어야 한다는 것이다.

재사용을 목적에 두면 좀 더 나은 리팩토링을 수행해볼 수 있을 것 같다.

리팩토링이란 건 참으로 어려운 것 같다...

profile
쥐눈(Jin Hoon)

0개의 댓글