-
[VanillaJS] 투두리스트 구현하기(下)JavaScript/VanillaJS 2022. 10. 30. 16:48728x90반응형
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'JavaScript > VanillaJS' 카테고리의 다른 글
[VanillaJS] 투두리스트 구현하기(上) (0) 2022.10.23 [VanillaJS] 랜덤 모듈로 명언, 배경화면 구현하기 (0) 2022.10.22 [VanillaJS] 시계 구현하기 (0) 2022.10.18 [VanillaJS] 로그인창 구현하기 (0) 2022.10.14