2차 공부/TIL

24.08.12 개인과제 리팩토링

공대탈출 2024. 8. 12. 20:40

 

페이지에서 입력한 값이 로컬스토리지에 저장되고, 브라우저를 껐다 키더라도 해당 데이터가 남아있게 하기 위해 로컬 스토리지를 사용하였다.

 

useEffect(() => {
    const countries = JSON.parse(localStorage.getItem("countries"));
    setTotal(countries);
}, []);

useEffect(() => {
    if (total.length > 0) localStorage.setItem("countries", JSON.stringify(total));
}, [total]);

useEffect를 사용하여 화면이 로드되고 난 뒤 localStorage에 있는 countries키의 값을 가져오고, 해당 값을 total State에 저장한다.

그리고 useEffect를 하나 더 사용하여 total에 값이 저장되어있을 때 localStorage에 total을 저장하도록 설정하였고, dependency 배열에 total을 넣어 해당 값에 변화가 있을 때마다 실행되게 하였다.

하지만 몇가지 문제가 발생했다.

 

1. 마지막 한개의 데이터가 state에선 변화되었지만, 로컬스토리지에선 삭제되지 않음

2. 로컬스토리지에서 삭제되지 않으니 새로고침을 하더라도 남은 해당 값이 페이지가 로드될 때 다시 total에 들어감

3. 마지막 한 값을 절대 비우지 못함

이런 문제가 있었다.

이 문제는 두번째 useEffect의 if문이 원인이었다. 해당 조건문이 존재하지 않으면 오류가 발생하여 넣은 것이었는데, total이 비워져 useEffect가 실행되지만, 조건문의 조건을 넘지 못해 비워진 total이 localStorage에 반영되지 못하는 것 이었다.

따라서 useEffect의 페이지 로드시 실행하는 부분을 없애야 했다.

import { useEffect, useRef } from "react";

const useDidMountedEffect = (func, deps) => {
    const isMounted = useRef(false);
    useEffect(() => {
        if (isMounted.current) func();
        else {
            isMounted.current = true;
        }
    }, [deps]);
};

export default useDidMountedEffect;

useDidMountedEffect 라는 커스텀 훅을 만들었다. 해당 훅은 실행될 함수 func와 의존성배열에 들어갈 deps를 인자로 받는다.

처음 페이지 로드시 isMounted.current는 false로 설정되어있어 useEffect에서 else부분이 실행된다.

그리고 deps에 변화가 있을 때마다 다시 실행되는데, 이때 isMounted.current는 true이므로 func가 실행된다.

const setLocalStorage = () => {
    localStorage.setItem("countries", JSON.stringify(total));
};
useDidMountedEffect(setLocalStorage, total);

로컬스토리지에 데이터를 넣는 함수 setlocalStorage를 만들어주고, 아까 만든 커스텀훅에 인자로 넣어주었다.


기능이 잘 작동되는 것을 보고 vercel으로 배포를 진행했다. 근데 null을 참조할수없다며 오류가 뜨는 것이다....

그래서 "아! vite로 만든 리액트프로젝트는 CRA와 달라서 뭔가 배포작업을 따로 해줘야하는건가?"했다.

그래서 뭐 yarn add global vercel npx vercel . vercel login... 

터미널에서 배포하는 작업을 따라해봤다.

근데 안됐다....

 

도대체 뭐가 문제지? 싶어 여기저기 둘러봤지만, vite로 만든 react프로젝트를 vercel에 배포할 때 뭔가 특별한 작업을 진행했다는 글은 어딜봐도 존재하지 않았다.

그래서 튜터님께 찾아갔다.

튜터님은 그럴리가 없는데... 하시면서 오류코드를 보시곤 코드에 문제가있는것 같다 하셨다.

localStorage의 값을 참조할 때 오류가 생기는 것이라고 말씀해주셔서 해당 부분을 고쳐보았다.

 

useEffect(() => {
    const countries = JSON.parse(localStorage.getItem("countries"));
    setTotal(countries);
}, []);

원래 코드는 이러했다. 페이지가 모두 로드되면 로컬스토리지에서 countries라는 키 값의 데이터를 가져와 total에 setState를 해주는 것.

하지만 개발환경에서는 계속 디벨롭하며 localStorage가 비어있을때가 없었다. 적어도 빈 배열이라도 존재했는데, 배포시에는 빈 배열조차 없으니 그런 에러를 뱉어내버리는 것이다.

따라서 빈 배열조차라도 있을 때 작동하도록 수정해야했다.

 

useEffect(() => {
    if (localStorage.getItem("countries")) {
        const countries = JSON.parse(localStorage.getItem("countries"));
        setTotal(countries);
    }
}, []);

로컬스토리지에 해당 값이 있을때 작업을 진행하도록 변경하였고, 버그를 해결하였다.