[유데미x스나이퍼팩토리] 10주 완성 프로젝트 캠프 18일차 - ReactJS: Todolist, 날씨

TK·2023년 6월 26일
0
post-thumbnail
  • 일시 : 23.06.26 월요일

🌱과제 리뷰

바닐라js로 코딩했던 todolist와 날씨를 리액트를 이용하여 새로 코딩해 보았다.

날씨는 리액트로 나타낼때

navigator.geolocation.getCurrentPosition()

위 함수를 사용하여 점에서 크게 다른 점은 없었고, 리액트 특징인 useState와 useEffect의 리액트 훅을 사용한다는 것에서 차이가 있었다. useState는 상태값을 관리해주고, useEffect는 컴포넌트가 렌더링 될 때 특정 작업을 실행할 수 있도록 한다.

todolist를 리액트로 바꾸는 과정도 수월할 것이라고 생각했으나 이 글을 쓰기까지 3일이 걸리게 만든 기능이었다. 이전에 바닐라js로 구현했던 부분에서는 목록을 나타내기 위해서는

const newTodoObj = {
    text: newTodo,
    id: Date.now(),
  };

위와 같이 id와 text를 가진 객체를 빈 배열안에 push 해주었고, 글 삭제는 클릭된 버튼 부모의 id와 같은 id를 목록에서 filter()를 통해 삭제(처럼 보이게) 해주면 되었다.

toDos = toDos.filter((toDo) => toDo.id !== parseInt(li.id));

그리고 이 기능들을 react에서는 상태관리 useState를 통해 더 쉽게 나타낼 수 있었다. 바닐라js에서 배열에 push했던 방식은, 다음과 같이 전개구문을 활용하여 이전 값과 함께 다시 리스트에 넣어줄 수 있었다.

setTodoList((oldList) => [newTodoObj, ...oldList])

삭제는 이전 방식과 동일하게 filter와 id를 사용하여 처리할 수 있었다.

💥문제 발생

(작성일: 23.06.29)
다만 문제는 로컬스토리지에 저장할 때 아주 다양한 문제를 맞닥뜨렸는데,

  1. 입력 받은 목록이 바로 로컬스토리지에 저장되지 않음. (다음 값을 입력해야 그 앞 값이 나타남. 혹은 두 번 이상 입력해야 두 번 앞의 값이 나타나기 시작함 등)
  2. 어쩌다 바로 로컬스토리지에 반영되게 한 후, 새로고침 하면 잘 저장되어 있지만 그 이후 목록을 입력하거나 값을 삭제하면 갑자기 로컬스토리지 값이 다 사라짐
  3. 로컬스토리지에 저장은 잘 되나, 새로고침하면 로컬스토리지 값이 다 사라짐
등 굉장히 오랜시간의 시행착오를 겪었다. 그래서 위와 같은 문제를 겪은 사람들의 사례를 열심히 찾아보았다.

https://codingapple.com/forums/topic/localstorage-데이터가-지워집니다/
https://velog.io/@tchaikovsky/REACT-localstorage가-바로-저장되지-않는다면

하지만 어떠한 것도 답이 되지 못했다. 아무래도 새로고침 하면서 빈 배열이 로컬스토리지에 저장되는 프로세스가 작동한 것 같은데 그 문제 코드를 아직 찾지 못했다. 더 지체하면 이 글을 쓰지 못할 것 같아서 일단 기록해 놓기 위해 적어보았다. 문제 코드와 화면은 아래 과제 내용에 영상을 첨부한다.


🌱과제 내용

구현 페이지

첫 화면


로그인 후 화면


할일 목록 작성


버그 영상

코드 보기

// Todo.jsx
// 이 코드는 버그가 있습니다. (수정 전)
import { useEffect, useState } from "react";

const TodoList = () => {
  const TODOS_KEY = "todos";
  const [todoList, setTodoList] = useState([]);
  const [todo, setTodo] = useState("");

  // localStorage 불러오기
  useEffect(() => {
    const savedList = localStorage.getItem(TODOS_KEY);
    if (savedList !== null) {
      setTodoList(JSON.parse(savedList));
    }
  }, []);

  // localStorage 저장
  useEffect(() => {
    localStorage.setItem(TODOS_KEY, JSON.stringify(todoList));
  }, [todoList]);

  const onChange = (e) => {
    setTodo(e.target.value);
  };

  const onSubmit = (e) => {
    e.preventDefault();
    if (todo === "") {
      return;
    }
    const newTodoObj = {
      text: todo,
      id: Date.now(),
    };
    setTodoList((oldList) => [newTodoObj, ...oldList]);
    setTodo("");
  };

  const deleteTodo = (e) => {
    setTodoList(
      todoList.filter((item) => item.id !== parseInt(e.target.parentElement.id))
    );
  };

  return (
    <div>
      <h1>My To Dos ({todoList.length})</h1>
      <form onSubmit={onSubmit}>
        <input
          onChange={onChange}
          value={todo}
          type="text"
          placeholder="Write your to do..."
        />
      </form>

      <ul>
        {todoList.length !== 0
          ? todoList.map((item, index) => (
              <li key={index} id={item.id}>
                <span>{item.text}</span>
                <button onClick={deleteTodo}>🗑️</button>
              </li>
            ))
          : "no data"}
      </ul>
    </div>
  );
};
export default TodoList;

깃허브 주소

코드보기

본 후기는 유데미-스나이퍼팩토리 10주 완성 프로젝트캠프 학습 일지 후기로 작성 되었습니다.

profile
쉬운게 좋은 FE개발자😺

0개의 댓글

관련 채용 정보