๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
JavaScript/Nomad Coders

[TIL] ๐Ÿ’ก Day 10 - JavaScript๋กœ TodoList ๋งŒ๋“ค๊ธฐ

by vividmin 2022. 5. 1.
320x100

โœ” ์ด ํฌ์ŠคํŒ…์€ ๋…ธ๋งˆ๋“œ์ฝ”๋” - "๋ฐ”๋‹๋ผ JS๋กœ ํฌ๋กฌ ์•ฑ ๋งŒ๋“ค๊ธฐ๋ฅผ ๋“ค์œผ๋ฉด์„œ ๊นƒํ—ˆ๋ธŒ์— ๊ธฐ๋กํ•œ ํ•„๊ธฐ๋ฅผ ์˜ฎ๊ธด ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค.

๋ชฉํ‘œ : ๐Ÿ“ JavaScript๋กœ Todo List ๋งŒ๋“ค๊ธฐ

 

๐ŸŒฑ Todo List ๊ธฐ๋ณธ ํ‹€ ์ค€๋น„

๐Ÿ‘‰ ์ผ๋‹จ ํ•„์š”ํ•œ ์š”์†Œ๋“ค์€ ์–ด๋–ค ๊ฒƒ์ด ์žˆ๋Š”์ง€ ์•Œ์•„๋ณด์ž.

  • Form : ์‚ฌ์šฉ์ž๊ฐ€ todo ์ž…๋ ฅ → ์ œ์ถœํ•˜๋Š” ํ˜•ํƒœ๊ฐ€ ํ•„์š”ํ•˜๋‹ค.
  • List : ์ž…๋ ฅํ•œ todo๋ฅผ ๋‚˜์—ดํ•ด์•ผ ๋œ๋‹ค.
  • input : ์‚ฌ์šฉ์ž์—๊ฒŒ todo๋ฅผ ์ž…๋ ฅ๋ฐ›์•„์•ผ ํ•œ๋‹ค.
  • ์˜ˆ์‹œ ์ฝ”๋“œ 
    <form id="todo-form"> 
      <input type="text" placeholder="Write a To Do and Press Enter" required /> 
    </form> 
    <ul id="todo-list"></ul>
      const toDoForm = document.getElementById("todo-form");
      const toDoInput = document.querySelector("#todo-form input");
      const toDoList = document.getElementById("todo-list");

      function paintToDo(newTodo) {       
        const li = document.createElement("li");        
        const span = document.createElement("span");    
        li.appendChild(span);                      
        span.innerText = newTodo;                   
        toDoList.appendChild(li);                  
      }

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

      toDoForm.addEventListener("submit", handleToDoSubmit);

 

  • ์ฃผ๋ชฉํ•  ๋งŒํ•œ ์ฝ”๋“œ
    // ๋‚˜์ค‘์— button๋„ ์ถ”๊ฐ€ํ•˜๊ธฐ ์œ„ํ•ด์„œ span์œผ๋กœ ๋งŒ๋“ ๋‹ค 
    li.appendChild(span); 

    /** ToDo๋Š” ์ž…๋ ฅ๋ฐ›์€ value๋Œ€๋กœ ๊ฐ๊ฐ ํ•œ ์ค„์”ฉ ์กด์žฌํ•œ๋‹ค. 
    input์˜ ํ˜„์žฌ value๋ฅผ ์ƒˆ๋กœ์šด ๋ณ€์ˆ˜์— ๋ณต์‚ฌํ•˜๊ณ  ์žˆ๋‹ค. 
    ๋ณต์‚ฌ ํ•œ ๊ฒƒ์ด๋ฏ€๋กœ ๋‹ค์Œ์— input์— ๋ญ˜ํ•ด๋„ ์•„๋ฌด ์ง€์žฅ์ด ์—†๋‹ค. 
    */ 

    const newTodo = toDoInput.value; 
    // todo Input์„ ๋น„์–ด ์žˆ๋Š” ์ƒํƒœ๋กœ ๋งŒ๋“ค์–ด ์ค€๋‹ค. 
    toDoInput.value = ""; 

    // paintToDo์— newTodo๋ฅผ ์ธ์ž๋กœ ์ฃผ๋ฉด์„œ ํ˜ธ์ถœํ•œ๋‹ค. 
    paintToDo(newTodo);
  • ๊ทธ ์™ธ ํ•ด๊ฒฐ์‚ฌํ•ญ
    • form์ด submit ํ›„ ์ƒˆ๋กœ๊ณ ์นจ ๋˜์ง€ ์•Š๋„๋ก ๊ธฐ๋ณธ ๋™์ž‘ ๋ง‰๊ธฐ ๐Ÿ‘‰๐Ÿป preventDefault( ) ์‚ฌ์šฉ
    • todo๋ฅผ ์ง€์šฐ๋Š” ๋ฒ„ํŠผ๋„ ๋งŒ๋“ค์–ด ๋ณด์ž.
    • ์ƒˆ๋กœ๊ณ ์นจ ๋’ค์—๋„ ์ž…๋ ฅํ•œ todo๊ฐ€ ์‚ฌ๋ผ์ง€์ง€ ์•Š๋„๋ก ๋งŒ๋“ค์ž.




๐ŸŒฑ Delete ToDos

๐Ÿ‘‰ todo ์‚ญ์ œ ๋ฒ„ํŠผ ๋งŒ๋“ค๊ธฐ

  • ์กฐ๊ฑด
    • ์ด ๋ฒ„ํŠผ์€ event๋ฅผ ์ˆ˜์‹ ํ•ด์•ผ ํ•œ๋‹ค.
    • append๋Š” ๋งˆ์ง€๋ง‰์— ๋„ฃ์–ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.
      ("todo list + ์‚ญ์ œ๋ฒ„ํŠผ"์ด ๋ฆฌ์ŠคํŠธ์˜ ํ•œ ์Œ์ด๋‹ค. ๊ฐ์ž ๋‹ค ๋งŒ๋“  ํ›„ li์— append!)
  • ์‚ญ์ œ ๋ฒ„ํŠผ ๋งŒ๋“ค๊ธฐ
    • ๋ฒ„ํŠผ ํƒœ๊ทธ ๋งŒ๋“ค๊ธฐ ์•ˆ์— ๋“ค์–ด๊ฐˆ ์š”์†Œ ๋„ฃ๊ธฐ (del or โŒ) ์ด๋ฒคํŠธ ์ˆ˜์‹ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ์„ค์ •
    function paintToDo(newTodo) { 
      const li = document.createElement("li"); 
      const span = document.createElement("span"); 
      span.innerText = newTodo; 
      const button = document.createElement("button");   //button ๋งŒ๋“ค๊ธฐ 
      button.innerText = "โŒ";      // button ์•ˆ์— x ์ด๋ชจํ‹ฐ์ฝ˜ ๋„ฃ๊ธฐ 
      button.addEventListener("click", deleteToDo); // ๋ฒ„ํŠผ ์ด๋ฒคํŠธ ์ˆ˜์‹  
      li.appendChild(span); 
      li.appendChild(button); 
      toDoList.appendChild(li); 
    }
  • ์š”์†Œ๋ฅผ ์‚ญ์ œํ•˜๋Š” deleteToDo ํ•จ์ˆ˜ ๋งŒ๋“ค๊ธฐ
    • ์—ฌ๋Ÿฌ ๊ฐœ์˜ todo ์ค‘์— ์–ด๋–ค ๊ฒƒ์„ ์ง€์›Œ์•ผ ํ• ์ง€ ์•Œ์•„์•ผ ํ•œ๋‹ค.
    • click์ด๋ฒคํŠธ๋ฅผ console๋กœ ํ™•์ธํ•ด๋ณด๋ฉด Path์—์„œ ๋ฒ„ํŠผ์ด li์— ํฌํ•จ๋˜์–ด ์žˆ๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.
  • deleteToDo ์ฝ”๋“œ
    function deleteToDo(event) { 
      const li = event.target.parentElement; 
      li.remove(); 
    }

 

 

๐ŸŒฑ Save ToDos

๐Ÿ‘‰ ์ƒˆ๋กœ๊ณ ์นจํ•ด๋„ ์‚ฌ๋ผ์ง€์ง€ ์•Š๋„๋ก ์ €์žฅํ•˜๊ธฐ.

  • toDos๋ผ๋Š” ์ด๋ฆ„์˜ ๋นˆ ๋ฐฐ์—ด ์„ ์–ธํ•˜๊ธฐ
    const toDos = [];
  • ์ƒˆ๋กœ์šด todo๊ฐ€ ์ƒ๊ธฐ๋ฉด toDos ๋ฐฐ์—ด์— ์ถ”๊ฐ€๋˜๋„๋ก ์„ค์ •
    toDos.push(newTodo);
  • localStorage์— toDos[] ์ €์žฅํ•˜๋Š” ํ•จ์ˆ˜ ๋งŒ๋“ค๊ธฐ
    (์ง€๋‚œ๋ฒˆ greeting์ฒ˜๋Ÿผ string ํ˜•ํƒœ๋กœ ์ €์žฅํ•ด์•ผ ํ•œ๋‹ค.)
    function saveToDos() { 
      localStorage.setItem("todos", JSON.stringify(toDos)); 
    }
  • paintToDo(newTodo) ๋’ค์— saveToDos ํ˜ธ์ถœํ•˜๊ธฐ
	saveToDos();
  • ์ตœ์ข… ์ฝ”๋“œ
    const toDos = [];

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

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



๐ŸŒฑ loading Todos

๐Ÿ‘‰ localStrage์— ์ €์žฅ๋œ todo list ๊ฐ€์ ธ์˜ค๊ธฐ

  • ํ˜„์žฌ๋Š” localStorage์—๋Š” ์ €์žฅ๋˜์–ด ์žˆ์ง€๋งŒ, ํ™”๋ฉด์—๋Š” ๋ณด์ด์ง€ ์•Š๋Š” ์ƒํƒœ์ด๋‹ค.
  • localStorage์— ์žˆ๋Š” string์„ array๋กœ ๋‹ค์‹œ ๋ณ€ํ™˜.
    • string ๊ฐ€์ ธ์˜ค๊ธฐ localStorage.getItem( ) ์‚ฌ์šฉ
  • todos๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ์“ฐ๋‹ˆ๊นŒ ์‹ค์ˆ˜๋ฅผ ์ค„์ด๊ธฐ ์œ„ํ•ด์„œ ๋ณ€์ˆ˜๋กœ ์„ ์–ธ.
    • const TODOS_KEY = "todos";
  • savedToDos๊ฐ€ null์ผ ๊ฐ€๋Šฅ์„ฑ ๊ณ ๋ คํ•ด์•ผ ํ•จ.
  • forEach ์‚ฌ์šฉํ•ด์„œ ๊ฐ list ํ™”๋ฉด์— ๋ฟŒ๋ ค์ฃผ๊ธฐ.
    • js๋Š” array์— ์žˆ๋Š” ๊ฐ๊ฐ์˜ item์— ๋Œ€ํ•ด fuction์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด ์ค€๋‹ค.
    • parsedToDos๋Š” ๋ฐฐ์—ด์ด๋ฏ€๋กœ, forEach๋ผ๋Š” ๊ฒƒ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.
      forEach๋Š” item์— ๋Œ€ํ•ด ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด ์ค€๋‹ค.
  • ๐Ÿ’ก JS Tip!
    • 1๋ฒˆ, 2๋ฒˆ ๋ฐฉ๋ฒ•์€ ๋™์ผํ•œ ํ‘œํ˜„๋ฒ•์ด๋‹ค.
    • 2๋ฒˆ : ํ™”์‚ดํ‘œ ํ•จ์ˆ˜ ์‚ฌ์šฉ๋ฐฉ๋ฒ•
	// 1๋ฒˆ
    function sayHello(item) {
      console.log("this is the turn of", item)
    }
    parsedToDos.forEach(sayHello);

    // 2๋ฒˆ
    parsedToDos.forEach((item) => console.log("this is the turn of ", item));
  • ์šฐ๋ฆฌ๋Š” ์ด๋ฏธ todo list๋ฅผ ๊ทธ๋ฆฌ๋Š” paintToDo( )๊ฐ€ ์žˆ๋‹ค.
    • paintToDo๋Š” newItem์ด๋ผ๋Š” ์ธ์ž๊ฐ€ ํ•„์š”ํ•œ๋ฐ ์ด ์ธ์ž๊ฐ€ ๊ณง localStorage์—์„œ ๊ฐ€์ ธ์˜จ parsedTodo์ด๋ฏ€๋กœ
      ๊ทธ๋ƒฅ paintToDo๋งŒ forEach์— ๋„ฃ์–ด์ฃผ๋ฉด ๋œ๋‹ค.
  •  
  • loading Todos ์ฝ”๋“œ
    const TODOS_KEY = "todos";

    const savedToDos = localStorage.getItem(TODOS_KEY);

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

 

    • ์—ฌ๊ธฐ๊นŒ์ง€ ํ–ˆ์„ ๋•Œ ๋ฌธ์ œ์ โ“
      • ์ด ์ƒํƒœ๋Š” ์ƒˆ๋กœ ์ €์žฅ๋œ list๋งŒ localStorage์— ์ €์žฅํ•˜๊ณ  ์ด์ „ ๊ฒƒ์€ ์ง€์›Œ๋ฒ„๋ฆฐ๋‹ค.
      • ์ด์œ ?
        • ์‹œ์ž‘ ์‹œ ํ•ญ์ƒ ๋น„์–ด์žˆ๋Š” [ ]์ด๋ผ์„œ paintToDo๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ๋งˆ๋‹ค ๊ฐ’์„ ๋ฎ์–ด์“ฐ๊ธฐ ํ•œ๋‹ค.
 const toDos = [];
    • ํ•ด๊ฒฐ๋ฐฉ์•ˆ
      • let์œผ๋กœ ๋ฐ”๊ฟ”์„œ ์—…๋ฐ์ดํŠธ ๊ฐ€๋Šฅํ•˜๋„๋ก ์„ค์ •
      • localStorage์— ์ด์ „ list๊ฐ€ ์žˆ์œผ๋ฉด toDos์— parsedToDos๋ฅผ ๋„ฃ์–ด์„œ ์ „์˜ toDo๋ฅผ ๋ณต์›.
  • ์ˆ˜์ •๋œ ์ฝ”๋“œ
    let toDos = [];

    if (savedToDos !== null) {
      const parsedToDos = JSON.parse(savedToDos);
      toDos = parsedToDos;
      parsedToDos.forEach(paintToDo);
    }
  • ์ถ”๊ฐ€๋กœ ํ•ด๊ฒฐํ•  ๋ฌธ์ œ โ“
    • delete๋ฅผ ํ•ด๋„ ์ƒˆ๋กœ๊ณ ์นจ ํ•˜๋ฉด ์‚ด์•„๋‚œ๋‹ค.
    • localStorage์—์„œ ์‚ญ์ œ๊ฐ€ ์•ˆ ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ด๋ณด์ž.




๐ŸŒฑ Delete Todos 2

๐Ÿ‘‰ ์‚ญ์ œ ๋ฒ„ํŠผ ๋ˆ„๋ฅด๋ฉด localStrage์—์„œ๋„ ์‚ญ์ œ๋˜๋„๋ก ๋งŒ๋“ค๊ธฐ.

  • ์–ด๋–ค todos text๊ฐ€ ์ง€์›Œ์ง€๋Š”์ง€ ์•Œ์•„์•ผ ํ•œ๋‹ค.
    • todos๋ฅผ ๋งŒ๋“ค ๋•Œ id๋ฅผ ์ฃผ๋„๋ก ๋งŒ๋“ค์ž
    • ๋žœ๋ค id ๋งŒ๋“ค๊ธฐ -> Date.now() ์‚ฌ์šฉ (todo๊ฐ€ ๋งŒ๋“ค์–ด์งˆ ๋•Œ์˜ ๋‚ ์งœ์™€ ์‹œ๊ฐ„)
    • ์ด์ „: ์‚ฌ์šฉ์ž๊ฐ€ ์ ์–ด๋‘” text๋ฅผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋กœ push
    • ํ˜„์žฌ : object๋ฅผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋กœ push
    function handleToDoSubmit(event) {
      event.preventDefault();
      const newTodo = toDoInput.value; 
      const newTodoObj = {
        text: newTodo,
        id: Date.now(),
      };
      toDos.push(newTodoObj);
      paintToDo(newTodoObj);
      saveToDos();
    }
  • newToDoObj๊ฐ€ ๋์œผ๋‹ˆ๊นŒ paintTodo์˜ ๋‚ด์šฉ์„ ์กฐ๊ธˆ ๋ณ€๊ฒฝํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.
    function paintToDo(newTodo) {
      const li = document.createElement("li");

       // ๊ฐ list์— id๊ฐ’์„ ์ค€๋‹ค.
      li.id = newTodo.id;

      const span = document.createElement("span");

       // ์ด๋ ‡๊ฒŒ ํ•ด์ฃผ์ง€ ์•Š์œผ๋ฉด ํ™”๋ฉด์— objectํ˜•ํƒœ๋กœ ํ‘œ์‹œ๋œ๋‹ค.
      span.innerText = newTodo.text;

      const button = document.createElement("button");
      button.innerText = "โŒ";
      button.addEventListener("click", deleteToDo);
      li.appendChild(span);
      li.appendChild(button);
      toDoList.appendChild(li);
    }
  • ์ด์ œ x ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅผ ๋•Œ ๊ทธ list์˜ id๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์œผ๋ฉด localStorage์—์„œ๋„ ์‚ญ์ œ๊ฐ€ ๊ฐ€๋Šฅ
  • array์—์„œ element ์‚ญ์ œํ•˜๋Š” ๋ฐฉ๋ฒ•?
    ๐Ÿ‘‰๐Ÿป filter ์‚ฌ์šฉ
    • ์‹ค์ œ๋กœ element๋ฅผ array์—์„œ ์ง€์šฐ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์ง€์šฐ๊ณ  ์‹ถ์€ item์„ ๋นผ๊ณ  ์ƒˆ array๋ฅผ ๋งŒ๋“ ๋‹ค. (๋งค์šฐ ์ค‘์š”โœจ)
    • filter(ํ•จ์ˆ˜)์˜ ํ˜•ํƒœ๋กœ ์‚ฌ์šฉ
    • filter๋Š” forEach์ฒ˜๋Ÿผ ๊ฐ item์„ ๋„ฃ์–ด์„œ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.
    • array์˜ item์„ ์œ ์ง€ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด filter์•ˆ์˜ ํ•จ์ˆ˜๋Š” ๋ฐ˜๋“œ์‹œ true๋ฅผ ๋ฆฌํ„ดํ•ด์•ผ๋งŒ ํ•œ๋‹ค.
    • false๋ฅผ ๋ฆฌํ„ดํ•œ๋‹ค๋ฉด ์ƒˆ array์— false๋ฅผ ๋ฆฌํ„ดํ•œ item์€ ๋“ค์–ด๊ฐ€์ง€ ์•Š๋Š”๋‹ค.
  • ์ด ๊ฐœ๋…์œผ๋กœ localStorage์—์„œ๋„ ์‚ญ์ œ๋˜๋„๋ก ๋งŒ๋“ค์–ด๋ณด์ž.
    • ๋ฒ„ํŠผ์„ ํด๋ฆญํ•  ๋•Œ๋งˆ๋‹ค list์˜ id๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค.
    • array์— ์žˆ๋Š” item์˜ id!== ํด๋ฆญ๋œ id => ์ƒˆ array์— ์ถ”๊ฐ€๋˜๋„๋ก filter๋ฅผ ์„ค์ •
	toDos = toDos.filter((toDo) => toDo.id !== li.id);
  • ๊ทธ๋Ÿฐ๋ฐ ์—ฌ๊ธฐ๊นŒ์ง€ ํ•˜๋ฉด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.
    ๐Ÿ‘‰๐Ÿป ๋ณ€์ˆ˜์˜ type ๋•Œ๋ฌธ์— ์ œ๋Œ€๋กœ ๋™์ž‘ํ•˜์ง€ โŒ
    • li์˜ id๋Š” string, ์ด๊ฒƒ์„ number๋กœ ๋ฐ”๊พธ์–ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.
    • ๊ทธ๋‹ค์Œ ์ƒˆ๋กœ ๋งŒ๋“ค์–ด์ง„ array๋ฅผ toDos์— ์—…๋ฐ์ดํŠธํ•ด์ค€๋‹ค.
    toDos = toDos.filter((toDo) => toDo.id !== parseInt(li.id));
    saveToDos();




๐ŸŒฑ Todo List ์™„์„ฑ ๋ฒ„์ „

๐Ÿ‘‰ ์ „์ฒด์ ์œผ๋กœ ํ•ด๊ฒฐ ๋ฐฉ์•ˆ์ด ์ ์šฉ๋œ ์ฝ”๋“œ

- html ์ฝ”๋“œ

    <form id="todo-form">
      <input type="text" placeholder="Write a To Do and Press Enter" required />
    </form>
    <ul id="todo-list"></ul>

- js ์ฝ”๋“œ

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

    const TODOS_KEY = "todos";

    let toDos = [];

    function saveToDos() {
      localStorage.setItem(TODOS_KEY, JSON.stringify(toDos));
    }

    function deleteToDo(event) {
      const li = event.target.parentElement;
      li.remove();
      toDos = toDos.filter((toDo) => toDo.id !== parseInt(li.id));
      saveToDos();
    }

    function handleToDoSubmit(event) {
      event.preventDefault();
      const newTodo = toDoInput.value;
      toDoInput.value = "";
      const newTodoObj = {
        text: newTodo,
        id: Date.now(),
      };
      toDos.push(newTodoObj);
      paintToDo(newTodoObj);
      saveToDos();
    }

    function paintToDo(newTodo) {
      const li = document.createElement("li");
      li.id = newTodo.id;
      const span = document.createElement("span");
      span.innerText = newTodo.text;
      const button = document.createElement("button");
      button.innerText = "โŒ";
      button.addEventListener("click", deleteToDo);
      li.appendChild(span);
      li.appendChild(button);
      toDoList.appendChild(li);
    }

    toDoForm.addEventListener("submit", handleToDoSubmit);

    const savedToDos = localStorage.getItem(TODOS_KEY);

    if (savedToDos !== null) {
      const parsedToDos = JSON.parse(savedToDos);
      toDos = parsedToDos;
      parsedToDos.forEach(paintToDo);
    }
๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€