7.3 Saving To Dos

정진우·2023년 1월 2일
0
post-thumbnail

ToDo를 추가할 수도 삭제할 수도 있게 만들었지만 페이지를 새로고침 하면 작성했던 ToDo가 사라진다. ToDo가 사라지지 않고 저장될 수 있도록 만들어보자.


📌 localStorage

localStrage는 웹 스토리지 객체(web storage object)로 브라우저에 키(key)와 값(value)으로 이루어진 데이터를 저장할 수 있습니다. localStrage의 경우 여러 탭이나 창 간에 데이터가 서로 공유되며 탭이나 창을 닫아도 데이터는 브라우저에 그대로 남아 있습니다. 즉 웹페이지의 세션이 끝나더라도 데이터가 지워지지 않고 유지됩니다.

◎ LocalStorage 사용 방법

// 키에 데이터 쓰기
localStorage.setItem("key", value);

// 키로 부터 데이터 읽기
localStorage.getItem("key");

// 키의 데이터 삭제
localStorage.removeItem("key");

// 모든 키의 데이터 삭제
localStorage.clear();

// 저장된 키/값 쌍의 개수
localStorage.length;

브라우저 콘솔창을 열어서 테스트 해보자

// setItem
localStorage.setItem('name', 'Tim')
localStorage.setItem('age', '35')

// getItem
const name = localStorage.getItem('name')
const age = localStorage.getItem('age')

// result
console.log(name) // Tim
console.log(age) // 35

// 저장된 키/값 쌍의 개수
localStorage.length // 2

// removeItem
localStorage.removeItem('age')
localStorage.removeItem('name')

// 저장된 키/값 쌍의 개수 재확인
localStorage.length // 0

‼️ 주의 사항

localStorage에는 문자열만 저장됩니다. localStorage 는 문자열 데이터 밖에 저장할 수 없기 때문에, 다른 타입의 데이터를 저장하려고 할 때 문자형으로 변환을 해서 저장해야 합니다.

localStorage.setItem('num', 1) // undefined

localStorage.getItem('num') === 1 // false

localStorage.getItem('num') // "1"

typeof localStorage.getItem('num') // "string"

localStorage에 객체나 배열을 저장하기 위해서는 객체를 문자열로 변환해서 저장해야 하기 때문에, JSON.stringify() 함수를 사용하여 객체와 배열을 JSON 문자열로 변환해야 한다.

localStorage.setItem('obj', {a:1, b:2}) // undefined

localStorage.getItem('obj') // "[object Object]" 

// JSON.stringify()를 사용해서 객체를 문자열로 변환
localStorage.setItem('obj', JSON.stringify({a:1, b:2})) // undefined

localStorage.getItem('obj') // '{"a":1,"b":2}'

JSON.stringify: 객체 -> 문자열

JSON.parse: 문자열 -> 객체


일단 toDos라는 이름의 배열을 하나 만들어준다.

const toDos = [];

그리고 todo list가 추가될 때, newToDo가 추가될 때 마다 그 텍스트를 toDos배열에 push 하려고 한다.

function paintToDo(newToDo) {
  const li = document.createElement("li");
  const span = document.createElement("span");
  span.innerText = newToDo;
  const button = document.createElement("button");
  button.innerText = "❌";
  button.addEventListener("click", deleteToDo);
  toDoList.appendChild(li);
  li.appendChild(span);
  li.appendChild(button);
}

그래서 newTodo의 입력값을 paintToDo() 함수에 넣어 호출하기 전에 newToDo를 todos배열에 가지고와서 push 해준다.

function handleToDoSubmit(event) {
  event.preventDefault();
  const newTodo = toDoInput.value;
  toDoInput.value = "";
	todos.push(newTodo)
  paintToDo(newTodo);
}

콘솔 창에 toDos를 입력하고 확인해 보면 배열에 추가된 것을 볼 수 있다. 이제 이것들을 localStorage에 추가해 볼 텐데 문제가 하나 있다. 위에서 localStorage를 알아본 것처럼 localStorage는 문자열만 저장할 수 있기 때문에 다른 타입의 데이터를 저장하려고 할 때 문자형으로 변환을 해서 저장해야 하기 때문이다. 일단 변환하지 않고 그냥 진행해 보자.

saveToDos라는 이름을 가진 함수를 하나 만들어준다. saveToDos가 하는일은 toDos배열의 내용을 localStorage에 넣어주는 일이다

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

사용자가 form을 submit을 하면 작성된 input 창을 비우고 작성한 내용(newToDo)을 toDos 배열에 push 한 다음 화면에 작성한 내용 todo를 추가한 뒤 작성한 todo를 localStorage에 저장한다.

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

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

toDoForm.addEventListener("submit", handleToDoSubmit);

내용을 입력하고 개발자 도구에서 Application을 확인해 보면 작성한 내용이 localStorage에 저장된 것을 확인할 수 있다.

그리고 추가로 입력할 때마다 localStorage에 추가되는 걸 알 수 있다.

그런데 새로고침을 하면 localStorage에는 저장되어 있지만 화면에 나타나질 않는다. 그리고 새로 내용을 작성하면 기존에 저장되어 있던 내용이 없어지고 새로 작성한 내용이 추가된다. 일단 이 문제는 잠시 멈추고(다음강의에서 진행)

위에서 localStorage에 저장된 value를 보면 작성한 내용은 문자열로 저장된다. localStorage는 문자열만 저장할 수 있기 때문에 객체나 배열을 저장하기 위해서는 객체를 문자열로 변환해서 저장해야 하기 때문에 JSON.stringify() 함수를이용해 객체와 배열을 JSON 문자열로 변환해서 사용해보자.

저장된 내용이 문자열(String)의 형태가 아닌 배열(Array)의 형태로 저장되길 원하기 때문에 바꿔보자. JSON.stringify()함수를 이용해 작성하고 Application을 확인해보면 배열의 형태로 저장된것을 볼 수 있다.

localStorage.setItem("todos", JSON.stringify(toDos))

다음 강의에선 아까 잠시 멈췄던 문제를 해결해보자.

const toDoForm = document.getElementById("todo-form");
const toDoInput = document.querySelector("#todo-form input");
const toDoList = document.getElementById("todo-list");

const toDos = [];

// toDos의 내용을 localStorage에 넣어주는 함수
function saveToDos() {
  localStorage.setItem("todos", JSON.stringify(toDos));
  // JSON.stringify()를 이용해 객체나 배열을 문자열로 변환해준다.
}

// todo list가 제거되는 함수
function deleteToDo(event) {
  // 현재 event.target의 부모요소를 찾아준다
  const li = event.target.parentNode;
  li.remove();
}

// 매개변수로 들어간 newToDo는 상수 newToDo와 관계없다
// todo list가 추가되는 함수
function paintToDo(newToDo) {
  const li = document.createElement("li");
  const span = document.createElement("span");
  span.innerText = newToDo;
  // span의 텍스트는 handleToDoSubmit() 함수에서 온 newToDo 텍스트가 된다.
  const button = document.createElement("button");
  button.innerText = "❌";
  button.addEventListener("click", deleteToDo);
  toDoList.appendChild(li);
  li.appendChild(span);
  li.appendChild(button);
}

function handleToDoSubmit(event) {
  event.preventDefault();
  // preventDefault()는 어떤 event의 기본 동작이 발생되지 않도록 막아준다.
  // ex: submit event는 새로고침을 하는데 그 기능을 막아준다.
  const newTodo = toDoInput.value;
  // toDoInput.value의 값을 저장하는 변수
  toDoInput.value = "";
  // toDoInput.value에 빈 값(””)을 넣어주고 내용을 작성한 뒤 엔터를 누르면 input 창이 비워진다.
  toDos.push(newTodo);
  // toDoInput.value의 값을 todos배열에 push 해준다.
  paintToDo(newTodo);
  // 변수 newTodo의 입력값을 paintToDo() 함수에 넣어 호출
  saveToDos();
  // toDos의 내용을 localStorage에 넣어주는 함수
}

toDoForm.addEventListener("submit", handleToDoSubmit);
profile
내가 바뀌지 않으면 아무것도 바뀌지 않는다 🔥🔥🔥

0개의 댓글