ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [JavaScript] 투두리스트 만들기 - 생성한 아이템 저장하고 불러오기 (2)
    만학도 프로젝트/JavaScript TodoList 2024. 3. 24. 22:00

     

    지난 글 정리

    지난 글에서 로컬스토리지에 할 일들을 저장하는 기능까지 완료했었습니다.

    지금까지 완성한 코드를 실행해보면 아이템들이 잘 생성되기도 하고 로컬스토리지에 저장도 되지만, 막상 페이지를 새로고침하면 모두 사라지는 상태인데요. 

    심지어 그 상태에서 새로고침을 한 이후에 새로운 아이템들을 생성하게 되면 아래 이미지처럼 로컬 스토리지에 저장된 아이템과, 화면에 보이는 아이템들 간의 차이도 발생하게 됩니다.

    그럼 지금부터는 페이지를 새로고침했을 때 로컬스토리지에 저장된 값을 불러와서 화면에 그려주는 것까지 마무리해볼게요.

     

    load 함수 만들기

    일단 그럼 로컬스토리지에 있는 데이터를 가져와서 아이템을 추가해 주는 함수를 한번 만들어봅시다.

    // ... addTodoItem ... 
    
    const loadTodoItem = () => {
      getTodos().forEach((todo) => addTodoItem(todo.title));
    };
    
    // ... clearTodoInput ...

     

    미리 만들어둔 getTodos 함수와 addTodoItem 함수가 있어서 생각보다 간단하게 load 함수를 만들 수 있었는데요.

    위치는 addTodoItem 아래에 선언해 줬습니다.

     

    로직을 요약해 보면 getTodos 함수로 저장된 아이템들을 불러오고, forEach 메서드를 이용해서 각 아이템들의 title로 addTodoItem 함수를 실행해 주는 내용입니다.

     

    init 함수 만들기

    이제 앞서 만든 load 함수를 이제 실행만 시켜주면 되는데, submit이벤트를 등록하는 부분 근처에서 실행시켜 줄 건데요.

    그전에 한 가지 작업을 더 해보려고 합니다. 페이지가 로드되었을 때 일어나야 할 작업들을 한 군데 모아주는 작업을 해보려고 하는 건데요.

    지금까지 작업한 내용으로 봤을 땐 처음 페이지에 접근했을 때 해야 할 일은 다음과 같습니다.

    1. todoForm에 submit 이벤트를 등록해 주는 일
    2. loadTodoItem 함수를 실행시키는 일

    여기에 clearTodoInput 함수를 실행시키는 것까지 포함해서 총 3가지 일을 수행하는 init 함수를 다음과 같이 만들어봤어요.

    // 기존의 "todoForm.addEventListener('submit', handleFormSubmit);" 코드는 삭제했어요.
    
    const initTodoApp = () => {
      todoForm.addEventListener('submit', handleFormSubmit);
      loadTodoItem();
      clearTodoInput();
    };

    그리고 이 함수를 페이지의 콘텐츠가 완전히 로드된 다음에 실행시키도록 해볼 건데요.

    방법은 다음과 같이 document 객체에 DOMContentLoaded 이벤트 핸들러를 등록해 주면 됩니다.

    // ...
    
    document.addEventListener('DOMContentLoaded', initTodoApp);

     

    이렇게 코드를 구성한 이유는

    initTodoApp 함수로 페이지가 완전히 로드된 다음에 반드시 필요한 행동들을 추상화하기 위함이고, 

    DOMContentLoaded 이벤트의 핸들러로 등록함으로써 페이지가 완전히 로드된 다음이라는 시점을 명확히 하기 위해서예요.

     

    마무리

    여기까지 js 코드를 한 번에 정리하면 아래와 같습니다.

    const todoForm = document.getElementById('todo-form');
    const todoInput = document.getElementById('todo-input');
    const todoList = document.getElementById('todo-list');
    const todoTemplate = document.getElementById('todo-template');
    
    const STORAGE_KEY = 'todos';
    
    const getTodos = () => {
      return JSON.parse(localStorage.getItem(STORAGE_KEY)) || [];
    };
    
    const saveTodoItem = (todoItem) => {
      const todoData = {
        title: todoItem.querySelector('.item-title').textContent,
      };
      const todos = getTodos().concat(todoData);
    
      localStorage.setItem(STORAGE_KEY, JSON.stringify(todos));
    };
    
    const createTodoItem = (itemTitle) => {
      const todoItem = todoTemplate.content
        .cloneNode(true)
        .querySelector('.todo-item');
    
      todoItem.querySelector('.item-title').textContent = itemTitle;
    
      return todoItem;
    };
    
    const addTodoItem = (itemTitle) => {
      const todoItem = createTodoItem(itemTitle);
    
      todoList.appendChild(todoItem);
      return todoItem;
    };
    
    const loadTodoItem = () => {
      getTodos().forEach((todo) => addTodoItem(todo.title));
    };
    
    const clearTodoInput = () => {
      todoInput.value = '';
    };
    
    const handleFormSubmit = (event) => {
      event.preventDefault();
    
      const inputValue = todoInput.value.trim();
    
      if (inputValue === '') return;
    
      saveTodoItem(addTodoItem(inputValue));
      clearTodoInput();
    };
    
    const initTodoApp = () => {
      todoForm.addEventListener('submit', handleFormSubmit);
      loadTodoItem();
      clearTodoInput();
    };
    
    document.addEventListener('DOMContentLoaded', initTodoApp);

    그리고 이 코드를 실행해 보면,

    이제 기존에 저장된 데이터들로 아이템들을 잘 불러와서 그려주는 모습까지 확인할 수가 있네요! :)

    새로고침해도 여전히 잘 남아있고요.

     

    여기까지 아이템을 생성하고 불러오는 기능은 잘 마무리된 것 같아요.

    다음에는 업데이트 기능을 만들어 보도록 하겠습니다.

     

    질문이나, 의문점이 드는 부분이라거나 제가 실수를 했다거나, 혹은 좀 더 좋은 방향이 있다면 댓글 부탁드립니다.

    더 좋은 글을 쓰고 제가 성장하는 데에도 큰 도움이 될 거예요! :)

    감사합니다.

    댓글

Designed by BigTop.