ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [VanillaJS] 투두리스트 구현하기(下)
    JavaScript/VanillaJS 2022. 10. 30. 16:48
    728x90
    반응형

    1. 투두리스트 값 저장하기 in localStorage

    1. 투두리스트 값 저장하기

    JSON.stringify

     

    화면에 투두를 입력해도 새로고침하면 사라지기 때문에 로컬 스토리지에 저장할 필요가 있다.

    const toDos = []; //투두리스트 저장할 배열
    
    // 로컬스토리지에 저장하는 함수
    function saveToDos() {
        localStorage.setItem("todos", toDos);
    }

    그리고 handleToDoSubmit() 함수에 seveToDos() 함수를 넣어준다.

    function handleToDOSubmit(event) {
        event.preventDefault();
        const newToDo = toDoInput.value;
        toDoInput.value = "";
        toDos.push(newToDo);
        paintToDo(newToDo);
        saveToDos();
    }

    입력이 될 때마다 투두리스트가 로컬스토리지에 저장됨.

     

    2. 투두리스트 값 배열로 저장하기

    여기서 문제가 하나 있는데 로컬 스토리지에 배열은 저장할 수 없다.

    -> 그래서 배열을 그대로 문자열화해서 저장한다.

     

    JSON 문자열로 변환하기

    JSON.stringify();

    괄호 안의 숫자나 변수나 배열을 JSON 문자열로 바꿀 수 있다.

    toDos배열을 문자열로 변환한 형태로 로컬스토리지에 "todos"라는 key값으로 저장한다.

    function saveToDos() { //
        localStorage.setItem("todos", JSON.stringify(toDos));
    }

     

    2. 투두리스트 값 불러오기 JSON

     

    1. 투두리스트 값 불러오기

     

    localStorage.getItem

    const TODOS_KEY = "todos"; // 실수가 없도록 상수화
    
    const savedToDos = localStorage.getItem(TODOS_KEY);
    // 로컬 스토리지에서 getItem으로 값 불러오기

    key값이 저장된 상수로 getItem을 해주고 savedToDos에 저장한다.

     

    2. 불러온 값 다시 배열로 만들기

     

    JSON.parse

    if(savedToDos) {
        const parsedToDos = JSON.parse(savedToDos);
        // 불러온 값을 배열로 만들어준다.
    }

    parse를 통해서 불러온 문자열 상태의 정보들을 배열형태로 만들어준다.

     

    3. 새로고침해도 이전에 입력했던 값 유지하기

    먼저 forEach구문을 통해 배열의 원소 하나하나에 접근한다.

    if(savedToDos) {
        const parsedToDos = JSON.parse(savedToDos);
    
        parsedToDos.forEach((item) => {
            console.log("This is turn of " + item);
        });
    }

    이전에 우리는 paintToDo 함수를 통해서 화면에 할 일을 띄울 수 있었다.

    forEach구문으로 배열 원소 하나씩 paintToDo 함수를 실행시켜주면 된다.

    if(savedToDos) {
        const parsedToDos = JSON.parse(savedToDos);
    
        parsedToDos.forEach(paintToDo); //
    }

    4. 새로고침 이전에 입력했던 값 불러오기

    여기서 또 하나 문제는 새로고침 한 후에도 투두리스트는 그대로 보이지만,

    새로운 할 일을 입력하면 배열이 리셋되어 새로고침 전에 입력했던 값은 사라진다는 것이다.

    이 문제는 localStorage에 있던 값을 미리 toDos에 대입함으로써 간단히 해결할 수 있다.

    let toDos = []; //투두리스트 저장할 배열

    먼저 toDos 배열을 const가 아닌 let으로 변경해준다.

    const savedToDos = localStorage.getItem(TODOS_KEY);
    
    // 로컬에 이전의 투두가 저장되어 있다면,
    if(savedToDos !== null) {
        const parsedToDos = JSON.parse(savedToDos);
        toDos = parsedToDos; // 배열에 이전 투두를 넣어줌.
        parsedToDos.forEach(paintToDo);
    }

    해결.

     

    3. 투두리스트 값 삭제하기

     

    1. Object 형식으로 Array 수정하기

     

    삭제할 때 보다 편리하게 하도록 하기 위해 Array 형식을 살짝 바꾸려고 한다.

     

    우리가 원하는 Object 형식

    [{id:12321, text:"drinks"}]

     

    여기서 랜덤ID 생성해서 id 값에 넣는다. -> Date.now()

    const newToDo = toDoInput.value; // input값의 value
    
    const newToDoObj = {
        id: Date.now(),
        text: newToDo,
    };

    입력받은 할 일을 text에 넣고 id를 랜덤 생성하여 삽입한다.

     

    기존 코드 살짝 수정하기

    function handleToDOSubmit(event) {
        event.preventDefault();
        const newToDo = toDoInput.value;
        toDoInput.value = "";
    
        const newToDoObj = {
            id: Date.now(),
            text: newToDo,
        };
        toDos.push(newToDoObj); // 인자를 newToDo에서 새로 만든 오브젝트 형식의 배열을 넣는다.
        paintToDo(newToDoObj); // 이하동문
        saveToDos();
    }

     

    2. 할 일 삭제하기

    filter()를 이용할 것이다.

    Array.filter(function());

    filter함수는 forEach와 비슷한데, 배열의 각 원소마다 함수를 실행시킨다.

    리턴값이 true이면 유지하고 false이면 제외시킨다.

    모든 원소에 함수를 실행시키고 제외한 item을 뺀 나머지 item들로만 새 배열을 형성한다.

     

    예.

    const arr = ["apple", "banana", "tomato"]
    
    function sexyFilter(food) { return food !== "banana" }
    
    arr.filter(sexyFilter)
    // ["apple", "tomato"]

    food가 "banana" 와 다르면 true 이므로, 다른 값들(apple, tomato)만으로 새 배열을 만든다.

    위와 같이 filter() 함수는 기존 Array에는 영향을 주지 않는다.

    또한 위의 sexyFilter와 같이 새로운 function 함수를 선언할 필요 없이 사용해도 똑같이 동작하는 것을 알 수 있다.

    따라서 todos의 array를 새 배열로 업데이트하고 업데이트 한 새 array를 localStorage에 저장해줘야 한다.

    function deleteToDo(event) {
        const li = event.target.parentNode;
        li.remove();
        toDos = toDos.filter((item) => item.id !== parseInt(li.id));
        saveToDos(); // 삭제한 후의 배열 로컬스토리지에 저장
    }

     

    4. 완성본

     

    todo.js

    const toDoForm = document.getElementById("todo-form");
    const toDoInput = document.querySelector("#todo-form input");
    const toDoList = document.getElementById("todo-list");
    
    let toDos = []; //투두리스트 저장할 배열
    const TODOS_KEY = "todos";
    
    function saveToDos() { //
        localStorage.setItem("todos", JSON.stringify(toDos));
    }
    
    function deleteToDo(event) {
        const li = event.target.parentNode;
        li.remove();
        toDos = toDos.filter((item) => item.id !== parseInt(li.id));
        saveToDos();
    }
    
    function paintToDo(newTodo) {
        const li = document.createElement("li");
        li.id = newTodo.id;
        const span = document.createElement("span");
        const button = document.createElement("button");
        li.appendChild(span);
        li.appendChild(button);
        span.innerText = newTodo.text;
        button.innerText = "X";
        toDoList.appendChild(li);
    
        button.addEventListener("click", deleteToDo);
    }
    
    function handleToDOSubmit(event) {
        event.preventDefault();
        const newToDo = toDoInput.value;
        toDoInput.value = "";
    
        const newToDoObj = {
            id: Date.now(),
            text: newToDo,
        };
        toDos.push(newToDoObj);
        paintToDo(newToDoObj);
        saveToDos();
    }
    
    toDoForm.addEventListener("submit", handleToDOSubmit);
    
    const savedToDos = localStorage.getItem(TODOS_KEY);
    
    if(savedToDos !== null) {
        const parsedToDos = JSON.parse(savedToDos);
        toDos = parsedToDos;
        parsedToDos.forEach(paintToDo);
    }
    LIST
Designed by Tistory.