광고 없는 나만의 To Do List 개발 일지 - 2. 화면에 todo 렌더링하기

Hanbin·2026년 2월 2일

나만의 To Do List

목록 보기
2/3
post-thumbnail

이전 글에서는 "왜 이 주제를 선정했는지?" 에 대한 배경을 이야기해 보았어요.

이번 글에서는 화면에 todo를 화면에 렌더링하기를 중점으로 내용을 구성해 보았습니다 :)




이전 글에서 프로젝트 배경에 대해 소개하였으니, 제일 먼저 화면에 todo를 띄우는 것부터 해보자!

1. todo를 화면에 렌더링하기

1) 임시 데이터(Mock Data) 선언

먼저 임시 데이터(Mock Data)로 사용할 todos 배열을 선언해주었다.

// Mock Data 선언
const todos = [
  {
    id: 0,
    contents: "빨래하기",
    isDone: true,
  },
  {
    id: 1,
    contents: "기술 블로그 작성하기",
    isDone: false,
  },
  {
    id: 2,
    contents: "OO은행 서류 제출",
    isDone: false,
  },
];

각각의 todo 객체는

  • id 값
  • todo의 내용을 의미하는 contents
  • 완료여부를 의미하는 isDone

등의 프로퍼티를 갖는 구조로 만들었다.



2) todo 렌더링 방식 결정

그 다음으로는, 이 todos 배열을 화면에 렌더링할 방식을 정해야겠다고 생각했다.


생각한 방식은 크게 두 가지가 있었다.
1️⃣ 자바스크립트 전역 코드(global code)에서 todo를 렌더링하는 방법
2️⃣ 렌더링을 담당하는 함수를 새로 하나 만드는 방법 ( ex. renderTodos() )

둘 중 어떤 방식이 더 적절할지 고민 끝에, 내가 만들고자 하는 To Do List가

  • todo 추가 / 수정 / 삭제 시 리렌더링
  • todo가 완료되면 재정렬

등의 기능이 있어야 했기 때문에 위와 같은 상태 변화가 일어날 때마다 todo를 다시 렌더링해 주려면,
초기 로딩 시 한 번만 실행되는 전역 코드(global code)보다는, 2️⃣번째 방법이었던 렌더링을 담당하는 함수( renderTodos() )로 분리하여 필요할 때마다 호출하여 사용하는 게 맞다고 생각했다.

const todoContainer = document.getElementById("todo-container");

// todo 상태 변화가 일어날 때마다 호출해서 사용할 함수
function renderTodos(todos) {
  const undoneTodo = todos.filter((todo) => !todo.isDone);  // 미완료 todo 배열
  const doneTodo = todos.filter((todo) => todo.isDone);     // 완료 todo 배열

  // undoneTodo와 doneTodo를 합친 배열
  const todoArr = [...undoneTodo, ...doneTodo];

  const todoHTML = todoArr
    .map(
      (todo) => `
	        // ... todo 한 개를 렌더링하는 HTML 부분
        `,
    )
    .join("");

  todoContainer.innerHTML = todoHTML;
}

미완료 todo가 완료된 todo보다 앞에 있어야하기 때문에 undoneTododoneTodo보다 앞에 오게끔 했다.




2. todo 완료 시, 재정렬하기

사진에서 볼 수 있듯이, “빨래하기”라는 todo처럼 todo가 완료되면 제일 밑으로 가게 되고 미완료 todo들이 상단에 머무를 수 있도록 재정렬되어야 한다. 완료된 todo보다는, 미완료 todo가 해결해야 할 우선순위가 더 높기 때문에 이렇게 기획했다.


이제 재정렬 기능을 구현해야 했는데, 어떤 방식으로 하는 게 좋을지 고민 끝에 아래와 같은 알고리즘을 생각했다.

  1. todo-container 안에 있는 대상 중, 변화(change)한 값에 한하여
  2. event의 target이 input[type="checkbox"] 일 때만
  3. 해당 checkbox를 가지고 있는 todo의 id 값을 찾아서
  4. 해당 todo 객체의 isDone 값을 변경 (true ↔ false)
  5. renderTodos() 함수를 통해 todo 리렌더링

const todoContainer = document.getElementById("todo-container");

// todo 완료(체크)할 때마다 리렌더링
todoContainer.addEventListener("change", (event) => {
  if (!event.target.matches('input[type="checkbox"]')) 
	  // 이벤트의 대상이 checkbox가 아니라면 return
	  return;

  const todoDiv = event.target.closest(".todo-task");
  const id = todoDiv.dataset.id;

  const todo = todos.find((data) => data.id == id);
  todo.isDone = event.target.checked;

  // todo 리렌더링
  renderTodos(todos);
});


다음 글에서는 todo 추가 / 수정 / 삭제 기능에 대해 작성할 예정입니다.

profile
Software Engineer

0개의 댓글