노마드코더 강의를 보면서 같이 To-do list를 만들었고, 이를 만들면서 자바스크립트를 더 잘 이해할 수 있었다!
🤔 새로고침해도 생성한 할 일들이 그대로 남아있었으면 좋겠어
프론트엔드 단에서도 값을 기억하는 방법이 있다. 바로 localStorage
를 이용하면 된다.
key와 value만 준비하면 로컬스토리지에서도 값을 저장할 수 있다.
로컬스토리지를 이용한 다양한 메서드는 여기서 확인할 수 있다.
const loginForm = document.querySelector("#login-form");
const loginInput = document.querySelector("#login-form input");
const greeting = document.querySelector("#greeting");
const HIDDEN = "hidden";
const USERNAME_KEY = "username";
// 중요한 정보가 아닌 단순 실수 방지를 위해 const 사용하는 경우 변수명 대문자로
function onSubmit(e) {
// console.log(loginInput.value);
e.preventDefault(); // 기본 동작 막음 // form을 submit해도 새로고침 안하도록 막음
loginForm.classList.add(HIDDEN);
const username = loginInput.value;
localStorage.setItem(USERNAME_KEY, username); // 로컬에 저장
// setItem("key", "value") // greeting.innerText = "Hello " + username;
// greeting.innerText = `Hello ${username}`; // 클린 코딩 `String ${변수명}`
// greeting.classList.remove(HIDDEN);
groupGreeting(username);
}
function groupGreeting(username){
greeting.innerText = `Hello ${username}`;
greeting.classList.remove(HIDDEN);
}
// username이 있는지 없는지 확인
const savedUsername = localStorage.getItem(USERNAME_KEY);
if (savedUsername === null ){
//show the form
loginForm.classList.remove(HIDDEN);
loginForm.addEventListener("submit", onSubmit);
}else{
//hide the form
groupGreeting(savedUsername);
}
// console.log(savedUsername); //로컬에 저장된 username value
argument를 이용해서 new value 와 saved value를 따로 둔다.
if 이후는 new value가 아닌 저장된 로컬 네임이 있는지 없는지 확인하는 것이기 때문에 saved value를 이용해야 한다.
🤗 왜 다른 argument를 이용하나 했는데 이렇게 생각하니 이해가 됐다.
아래의 경우 argument 사용할 필요없지만 localStorage를 두 번 열어봐야 한다.
const loginForm = document.querySelector("#login-form");
const loginInput = document.querySelector("#login-form input");
const greeting = document.querySelector("#greeting");
const HIDDEN = "hidden";
const USERNAME_KEY = "username";
// 중요한 정보가 아닌 단순 실수 방지를 위해 const 사용하는 경우 변수명 대문자로
function onSubmit(e) {
// console.log(loginInput.value);
e.preventDefault();
loginForm.classList.add(HIDDEN);
localStorage.setItem(USERNAME_KEY, username);
// greeting.innerText = `Hello ${username}`;
groupGreeting();
}
function groupGreeting(){
const username = localStorage.getItem(USERNAME_KEY);
greeting.innerText = `Hello ${username}`;
greeting.classList.remove(HIDDEN);
}
const savedUsername = localStorage.getItem(USERNAME_KEY);
if (savedUsername === null ){
//show the form
loginForm.classList.remove(HIDDEN);
loginForm.addEventListener("submit", onSubmit);
}else{
//hide the form
groupGreeting();
}
forEach
Array에 있는 각각의 item을 사용할 수 있게 해준다.
submit 이벤트 리스너가 event object를 기본으로 제공해주는 것처럼 JS도 item object를 기본으로 제공해준다.
function sayHello(item){
// console.log("hello", item); // hello item[0~]
}
// 저장되어 있는 Todo 가져오기
const savedTodos = localStorage.getItem(TODOS_KEY);
if(savedTodos !== null){
const parsedTodos = JSON.parse(savedTodos);
parsedTodos.forEach(sayHello);
}
화살표 함수 (더 간단하게 함수를 실행할 수 있다)
parsedTodos.forEach((item) => console.log(object));
🤗 각각의 item을 => 이 함수로 실행
parsedTodos.forEach(showTodo);
“각각의 item을 showTodo 함수로 실행시켜줘!”
🤗 여기서 showTodo 함수는 브라우저에 todo list를 보여주는 함수 ⇒ 저장된 각각의 item을 브라우저에 todo list로 보여준다.
이전 것(로컬에 저장된 것)과 새로운 것(새로 입력하는 할 일)을 모두 저장하고 싶다.
→ 먼저 로컬에 저장된 것이 사라지는 이유를 알아보자: todos = [] 비어있는 배열이기 때문에 계속 없어지는 것!
→ 그러면 비어있는 배열이 아닌 저장된 배열에 새로 추가하면 되겠다!
let todos = [];
if(savedTodos !== null){
const parsedTodos = JSON.parse(savedTodos);
// 저장된 배열이 존재하면 저장된 배열 + 새로운 배열 추가 해줘
todos = parsedTodos;
parsedTodos.forEach(showTodo);
}
🤔 이제 Todo list에 삭제 기능을 만들어보자
기존에는 사용자가 할 일을 입력하면 그대로 텍스트로 받았다. 하지만 이러면 컴퓨터가 어떤 할 일을 삭제해야 할지를 모른다.
function todoSubmit(e){
e.preventDefault();
const newTodo = todoInput.value;
todoInput.value = "";
todos.push(newTodo); // 새로운 todo 저장
showTodo(newTodo); // 사용자에게 받은 value 텍스트
saveTodos();
}
👇
Date.now() 를 이용하면 난수를 얻을 수 있다.
const newTodoOb = {
text: newTodo,
id: Date.now(),
};
todos.push(newTodoOb);
새로운 todo를 텍스트가 아닌 object로 저장
function todoSubmit(e){
e.preventDefault();
const newTodo = todoInput.value;
todoInput.value = "";
const newTodoOb = {
text: newTodo,
id: Date.now(),
};
todos.push(newTodoOb); // 새로운 todo 저장
showTodo(newTodoOb); // 사용자에게 받은 value 텍스트
saveTodos();
}
왜 object로 만들고, 난수를 얻으려고 하는 건가?
🤗 랜덤한 id값을 만들어, 일치하는 id값을 가진 할 일(todo)만 삭제하기 위함이다.
배열.filter(변수명)
forEach와 비슷하다.
function filterEx(item){
return item !== 3
// item이 3이 아니면 return true! // [1,2,4,5]
// item이 3일 경우 return false, 따라서 3인 item은 사라진다.
// 다시 말해, 3이 아닌 모든 item은 필터에 통과되는 것.
}
[1, 2, 3, 4, 5].filter(filterEx)
// array의 item을 유지하고 싶으면 true 리턴해야 함.
-----
// 자세한 예시
filterEx(1) = 1
filterEx(2) = 2
filterEx(3) = 3 // 만약 여기서 false가 발생하면 3을 제외한 filterEx(1,2,4)만 실행
filterEx(4) = 4
JS는 배열의 각 item을 해당 함수의 첫번째 argument로 전달한다.
⇒ argument는 배열의 각 item이 된다.
완성한 Todo list를 CSS로 꾸미고, 넣고 싶은 기능들을 혼자서 추가로 더 넣어봐야겠다! 🧐