useEffect 첫 렌더링 동작 막기

준영·2023년 6월 27일
0

코드 지갑..

목록 보기
13/20

사용이유

글 작성 페이지에 진입하면, useEffect를 사용하여, recoil에 저장된 로그인 여부를 판단해 로그인이 되어있지 않으면, 로그인 페이지로 이동 시키는 함수를 실행시킨다.

layout에 존재하는 로그인 상태를 변경하는 함수에서 렌더링이 일어날 때마다, firebase에서 제공하는 로그인 여부를 알려주는 메소드를 사용해서 recoil에 저장된 로그인 상태의 값을 바꿔주는데, 초기값이 false여서 글 작성 페이지에서 로그인 상태 recoil 값을 가져오는 useEffect에서 최초 렌더링 할 때, false인 값 때문에 바로 로그인 페이지로 보내버리는 문제를 겪게 되었다.

따라서 나는 useEffect의 첫 렌더링 이후에 (didMount => 컴포넌트가 마운트 된 후) 동작을 하게 만든다면 될 것 같다는 생각을 했다.

  • layout.tsx
    useEffect(() => {
        // login check func
        const loginCheck = () => {
            onAuthStateChanged(firebaseAuth, (user) => {
                if (user) {
                    setLoginStatus(true);
                    setUserInfo(user);
                    console.log(user);
                    console.log("check login OK!");
                } else {
                    setLoginStatus(false);
                    setUserInfo("");
                    console.log("check login NO!");
                }
            });
        };

        if (firebaseAuth) loginCheck();
    }, [firebaseAuth]);

따라서 custom hook을 만들어서 useEffect가 첫 렌더링 이후 동작하도록 만들어 보았다.

결론(custom hook)

// useEffect first rendering block
export const useDidMountEffect = (func: () => void, deps: any) => {
    const didMount = useRef(false);

    useEffect(() => {
        if (didMount.current) func();
        else didMount.current = true;
    }, deps);
};

hook 사용 예시

create.tsx

    useDidMountEffect(() => {
        if (userInfo === null || loginStatus === false) {
            router.push("/login");
        }

        if (
            userInfo?.email !== "내 이메일" &&
            loginStatus === true
        ) {
            router.push("/project");
        }
    }, [loginStatus, userInfo]);
profile
개인 이력, 포폴 관리 및 기술 블로그 사이트 👉 https://aimzero-web.vercel.app/

0개의 댓글