1편
1편에 이어서, toDo의 저장을 위해 Local Storage를 활용해보자.
Local Storage
항상 자바스크립트를 공부하면서 모르는 것이 있다면 구글을 열어서,keyword mdn
으로 검색하자.
예) local storage mdn
혼자 모르는 개념을 알아야 할 때 아주 좋고 상세하게 설명되어 있는 곳이다.
local storage란?
간단하게 말해서 내 브라우저에서 작은 정보를 기억해줄 수 있는 공간이다.
이 공간에 저장한 데이터는 브라우저의 기능을 이용하거나 내가 직접 삭제하지 않는 이상,
새로고침을 하거나 창을 껐다가 키는 것으로는 삭제되지 않는다.
그래서 이 이 공간에 toDo를 저장해서 활용할 수 있다.
setItem, getItem
localStorage에 데이터를 저장하거나 가져오는 방법으로 setItem, getItem이 있다.
순서대로, 저장하고, 가져오는 메서드이다.
localStorage에 저장된 데이터는 key:value 의 형태를 띄므로,
localStorage.setItem(key, value);
localStorage.getItem(key);
다음과 같이 데이터를 저장하거나 가져올 수 있다.
코드를 작성해보자.
HTML 문서는 이전 포스팅에서 작성한 내용과 같다.
지금부터 먼저 필요한 기능을 간단하게 생각해보고, 코드를 작성한 후 자세하게 살펴보자.
우리는 이미 To Do List를 작성했고, 이제 이 목록이 페이지가 새로고침 되어도 그대로 존재해야 한다.
우선 크게 보면 다음과 같다.
input에 입력한 데이터를 화면에 나타내면서, local Storage에도 그 데이터를 저장한다.
페이지가 새로고침 되었을 때, local Storage에 저장된 데이터를 먼저 불러와서 HTML 태그로 구현해서 보여줄 수 있다면?
이전 포스팅 JS 코드
const toDoForm = document.querySelector(".toDoForm");
const toDoInput = toDoForm.querySelector("input");
const toDos = document.querySelector(".toDos");
function paintToDo(toDo) {
const li = document.createElement("li");
const span = document.createElement("span");
span.innerHTML = toDo;
li.appendChild(span);
toDos.appendChild(li);
}
function createToDo(event) {
event.preventDefault();
const toDo = toDoInput.value;
paintToDo(toDo);
toDoInput.value = "";
}
function init() {
toDoForm.addEventListener("submit", createToDo);
}
init();
현재 코드의 실행 순서는 다음과 같다.
HTML 문서가 js파일을 불러오고, 가장 먼저 init 함수가 실행된다.
init함수에서는 form이 submit 될 때 createToDo 함수를 실행한다.
createToDo 함수가 입력한 toDo를 가지고, 화면에 toDo를 보여주기 위한 paintToDo 함수를 실행한다.
paintToDo 함수는 화면에 입력한 toDo를 보여준다.
우리는 toDo를 화면에 보여줄 때 local storage에도 toDo를 저장하고,
새로고침되어 init 함수를 실행할 때, local storage에 저장된 toDoList들을 먼저 불러와야 한다.
저장된 toDoList 불러오기
const toDoForm = document.querySelector(".toDoForm");
const toDoInput = toDoForm.querySelector("input");
const toDos = document.querySelector(".toDos");
const TODOLIST = "toDoList"; // 추가
function loadToDoList() {
const loadedToDoList = localStorage.getItem(TODOLIST);
if (loadedToDoList !== null) {
// toDoList가 있을 때
}
} // 추가
function init() {
loadToDoList(); // 추가
toDoForm.addEventListener("submit", createToDo);
}
init();
To Do 저장 시에 사용할 key 값을 위한 TODOLIST 상수를 선언한다.
init 함수를 실행할 때 우선 loadToDoList 함수를 먼저 실행해서
local Storage에 ToDo가 존재하는지 볼 것이다.
loadToDoList 함수에서 localStorage에서 key:"toDoList" 로 저장된 데이터가 있는지 보고, 있다면 특정 동작을 수행한다.
local storage에 toDo 저장하기
loadToDoList 함수를 완성하기에 앞서 우선 데이터를 먼저 저장해야 한다.
우리가 데이터를 저장하는 형태에 따라, loadToDoList 함수에 구현하는 코드가 정해지기 때문이다.
function saveToDo(toDo) {
localStorage.setItem(TODOLIST, toDo);
}
function createToDo(event) {
event.preventDefault();
const toDo = toDoInput.value;
paintToDo(toDo);
saveToDo(toDo);
toDoInput.value = "";
}
다음과 같이 코드를 작성하면 무엇이 문제일까?
setItem에 의해 저장된 데이터를 예상해보면,
"key" : "value" 의 모습으로
"toDoList" : "입력한 할 일" 로만 나타난다.
즉 1개의 데이터만 저장된다.
내가 새로운 toDo를 추가한다면 기존의 toDo는 없어지고 새로운 toDo만 남는 것이다.
배열 형태로 toDo들의 리스트를 만들어 그 배열을 저장해보자.
조금 더 생각해보면, 추후에 toDo 중에 "완료한 일"은 지우고 싶을 것이다.
배열에 toDo를 넣어줄 때 각각의 toDo간의 무결성을 보장하기 위한 id값도 함께 넣어주자.
const toDoForm = document.querySelector(".toDoForm");
const toDoInput = toDoForm.querySelector("input");
const toDos = document.querySelector(".toDos");
const TODOLIST = "toDoList";
let toDoList = []; // 추가
function saveToDo(toDo) {
const toDoObj = {
text: toDo,
id: toDoList.length + 1,
};
toDoList.push(toDoObj);
localStorage.setItem(TODOLIST, toDoList);
} // 수정
function createToDo(event) {
event.preventDefault();
const toDo = toDoInput.value;
paintToDo(toDo);
saveToDo(toDo);
toDoInput.value = "";
}
To Do List를 위한 배열 toDoList를 선언했다.
saveToDo 함수에서, 입력한 toDo를 가지고 {text:"toDo", id:1} 형태를 가진 toDoObj를 생성한다.
그리고 기존의 toDos 배열에 넣어주고, 그 배열을 local storage에 저장해준다.
toDos의 크기를 가지고 id를 생성하면, 데이터가 들어갈 때 마다 0,1,2,3 순으로 증가한다.
그러므로 id=1,2,3,4 ... 순으로 값이 부여되어 id로 toDo들을 구분할 수 있다.
이제 한번 데이터를 입력하고, 저장된 데이터를 보자.
Key 이름은 예상한 모습이지만, Value는 [object Object]라고 보인다.
local storage에 String 값이 아닌 값을 저장하려고 할 때는 타입을 변환해줘야 한다.
우리가 저장하려는 값은 Object(Array) 이므로,
JSON.stringify 메서드를 사용해서 객체를 JSON 문자열로 변환해서 저장해야 한다.
function saveToDo(toDo) {
const toDoObj = {
text: toDo,
id: toDoList.length + 1,
};
toDoList.push(toDoObj);
localStorage.setItem(TODOLIST, JSON.stringify(toDoList)); // 수정
}
결과를 보자.
올바른 형태로 저장 되었다.
새로고침을 해보자.
새로고침 후 HTML 태그는 모두 사라지지만, local storage에 데이터가 존재한다.
다시 loadToDoList 함수로 돌아가자
이제 local storage에 데이터가 존재하므로, loadToDoList 함수를 완성할 수 있다.
function loadToDoList() {
const loadedToDoList = localStorage.getItem(TODOLIST);
if (loadedToDoList !== null) {
const parsedToDoList = JSON.parse(loadedToDoList);
for (let toDo of parsedToDoList) {
const { text } = toDo;
paintToDo(text);
saveToDo(text);
}
}
}
우리가 toDoList를 저장할 때 JSON.stringify 를 이용했듯이, 불러올 때는 JSON.parse을 이용해서 불러와야 한다.
그렇지 않으면, 저장된 string값 그대로 가져와서 for 반복문에서 각 문자 하나를 toDo로 지정하는 참사가 벌어진다.
toDoList의 각 객체를 toDo라고 하고, 객체의 key(text)를 이용하자.
const {text} = toDo
는 const text = toDo.text;
와 같다.
이 변수를 paintToDo, saveToDo에 각각 넣어주면 된다.
이제 새로고침 시 기존 데이터를 불러오기 때문에 To Do List가 사라지지 않으며,
saveToDo 함수에 의해 local Storage에서 불러온 값을 바탕으로 기존 toDos 배열을 유지할 수 있다.
전체 코드
const toDoForm = document.querySelector(".toDoForm");
const toDoInput = toDoForm.querySelector("input");
const toDos = document.querySelector(".toDos");
const TODOLIST = "toDoList";
let toDoList = [];
function saveToDo(toDo) {
const toDoObj = {
text: toDo,
id: toDoList.length + 1,
};
toDoList.push(toDoObj);
localStorage.setItem(TODOLIST, JSON.stringify(toDoList));
}
function paintToDo(toDo) {
const li = document.createElement("li");
const span = document.createElement("span");
span.innerHTML = toDo;
li.appendChild(span);
toDos.appendChild(li);
}
function createToDo(event) {
event.preventDefault();
const toDo = toDoInput.value;
paintToDo(toDo);
saveToDo(toDo);
toDoInput.value = "";
}
function loadToDoList() {
const loadedToDoList = localStorage.getItem(TODOLIST);
if (loadedToDoList !== null) {
const parsedToDoList = JSON.parse(loadedToDoList);
for (let toDo of parsedToDoList) {
const { text } = toDo;
paintToDo(text);
saveToDo(text);
}
}
}
function init() {
loadToDoList();
toDoForm.addEventListener("submit", createToDo);
}
init();
To Do 삭제하기
아직 우리는, id를 활용하지 않았다.
각각의 toDo마다 가지고 있는 id를 이용해서 toDo를 삭제할 수 있다.
마지막 3편에서 toDo의 삭제를 다뤄보자.
'JavaScript > vanilla' 카테고리의 다른 글
[vanillaJS] 채팅창 컴포넌트의 스크롤을 다뤄보자. (0) | 2022.08.30 |
---|---|
[VanillaJS] 바닐라JS만으로 To Do List 만들어보자 3 (0) | 2021.04.30 |
[VanillaJS] 바닐라JS만으로 To Do List 만들어보자 1 (0) | 2021.04.30 |