[Mini Project] Todo-App / 구현, 배포하기

soohyunee·2023년 2월 10일

[Mini Project] Todo-App

목록 보기
2/3

CRUD 기능을 구현 했으니 이제 새로고침해도 값이 유지되게 하고, 배포를 하려고 한다. 파이어베이스를 활용하여 서버를 구축하고 배포를 하려고 했으나, 서버 구축은 오랜 시간 삽질 끝에 서버에 저장하는 것만 완성되고 데이터가 수정, 삭제 되었을 때 업데이트가 되지 않은 문제가 발생했다.
시간이 조금 부족해진 탓에 추후에 조금 더 공부하고 다시 적용해보기로 했다...

1. Todo 앱 구현하기

진행 사항

  • 로컬스토리지를 활용하여 데이터 저장

  • 파이어베이스 호스팅을 활용하여 배포

  • 오픈 그래프 추가

피드백

  • 모바일 반응형 : 적용 완료

  • 파비콘 교체 : 적용 완료


2. TIL

로컬스토리지 에러

전부 삭제한 후 새로 고침하면 빈 화면뜨는 에러 발생

Todo를 추가하고, 삭제버튼을 눌러서 전부 삭제한 후 새로 고침을 하면 빈 화면이 뜨는 에러 발생.. 로컬 스토리지를 열어보니 빈 배열만 존재했고, 로컬스토리지를 아예 비워주면 다시 제대로 화면이 나타났다.
이때 조건은 로컬스트로지에 데이터가 없을 때도 있으니 데이터가 있을 때만 값을 가져오는 걸로 작성했다.

useEffect(() => {
  const localData = localStorage.getItem("todo");
  if (localData) {
    const todoList = JSON.parse(localData).sort(
      (a, b) => parseInt(b.id) - parseInt(a.id)
    );
    dataId.current = parseInt(todoList[0].id) + 1;
    dispatch({ type: "INIT", data: todoList });
  }
}, []);

문제는 로컬스토리지에 있었는데 로컬스토리지에 데이터를 배열 형식으로 담다 보니 데이터를 삭제하면 결국 나중에 빈 배열만 남게 되는 것!
빈 배열은 truthy 하므로, 조건을 if(localData) 라고만 하게 되면 의도와는 다르게 값이 다 지워진 빈 배열의 상황에서도 dispatch 함수가 실행되고 에러가 발생하게 되는 것이라 생각했다.

시도한 방법

useEffect(() => {
  const localData = localStorage.getItem("todo");
  if (localData) {
 	JSON.parse(localData).sort((a, b) => 
    parseInt(b.id) - parseInt(a.id));
  }
  if (localData.length >= 1) {
	dataId.current = parseInt(localData[0].id) + 1;
	dispatch({type: "INIT", data: localData});
  }
}, []);

로컬스토리지에 값이 있으면서 빈 배열이 아닌 경우에만 dispatch 함수가 실행되게 하고자 위와 같이 조건을 추가하였지만 실패하였다.
첫 번째 방법은 dispatch 함수에 들어가는 data가 json.parse가 된 값을 넣어야 하는데 변수에 넣어주지 않은 채 로컬스토리지 값 자체를 전달해서 실패했다.

useEffect(() => {
  const localData = localStorage.getItem("todo");
  if (localData && localData.length >= 1) {
    const todoList = JSON.parse(localData).sort(
      (a, b) => parseInt(b.id) - parseInt(a.id)
    );
    dataId.current = parseInt(todoList[0].id) + 1;
    dispatch({ type: "INIT", data: todoList });
  }
}, []);

두번쨰 방법은 조건은 && 연산자로 조건을 묶어서 작성했는데, 이 방법도 마찬가지로 실패함.

useEffect(() => {
  const localData = localStorage.getItem("todo");
  if (localData) {
    const todoList = JSON.parse(localData).sort(
      (a, b) => parseInt(b.id) - parseInt(a.id)
    );
    if (localData.length >= 1) {
      dataId.current = parseInt(todoList[0].id) + 1;
      dispatch({ type: "INIT", data: todoList });
    }
  }
}, []);

세번째 방법은 조건문안에 조건을 또 써보았고, 이쯤에서 조건이 잘못인가라는 생각이 들어서 콘솔을 찍어봤다.
로컬스토리지가 빈 배열일때 localData는 [] 길이는 2, todoList는 값이 없고 길이는 0을 반환했다.
즉, localData 위에 setItem으로 저장할 때 JSON.stringify 되어 배열 형태이지만 문자열로 들어오고 있었던 것을 빈 배열이라고 착각하여 조건을 잘못 적은 탓에 계속 오류가 발생했던 것이다.

해결 방법

useEffect(() => {
  const localData = localStorage.getItem("todo");
  if (localData) {
    const todoList = JSON.parse(localData).sort(
      (a, b) => parseInt(b.id) - parseInt(a.id)
    );
    if (todoList.length >= 1) {
      dataId.current = parseInt(todoList[0].id) + 1;
      dispatch({ type: "INIT", data: todoList });
    }
  }
}, []);

이렇게 로컬데이터가 존재하면서, todoList의 값이 있을 경우에만 dispatch 함수가 실행되게 조건을 작성해주니 제대로 작동하였다.
역시 에러가 나면 콘솔을 찍어보는 게 중요한 것을 오늘 다시 깨달았다.

profile
FrontEnd Developer

0개의 댓글