개발/web

[Nextjs] useEffect vs useLayoutEffect

tting 2023. 3. 24. 12:49

페이지 접근시 토큰을 검증하는 과정을 추가하려 했다. Nextjs를 사용중이기에 서버측에서 검증하고 싶었으나 getServerSideProps나 api route를 사용하면 페이지 마다 로직을 추가해야하는 번거로움이 있어서 클라이언트에서 검증하는 방식으로 바꾸었다.

 

ssr시에는 router 객체를 가져올 수 없기에 useEffect로 렌더링 후에 체킹하도록 했다.

useEffect는 렌더링 후에 비동기적으로 실행되기 때문에 리다이렉트전에 블럭해야할 페이지가 잠깐 보이는 문제가 발생했다. 

 

useLayoutEffect는 페인팅전에 동기적으로 실행되기 때문에 페이지가 노출되는 현상을 막을 수 있다고 생각했다.

import { useRouter } from "next/router";
import React, { ReactNode, useEffect, useLayoutEffect } from "react";
import { useRecoilValue } from "recoil";
import sessionState from "@/lib/state/session";

const passPath = ["/login", "/signup"];

const Authentication = ({ children }: { children: ReactNode }) => {
  const session = useRecoilValue(sessionState);
  const router = useRouter();

  useLayoutEffect(() => {
    return () => {
      if (!session && !passPath.includes(router.pathname)) {
        router.push("/login");
      }
    };
  }, [session, router]);

  return <>{children}</>;
};

export default Authentication;

 

...

import Authentication from "@/components/auth/Authentication";

export default function App({ Component, pageProps }: AppProps) {
  const [queryClient] = useState(() => new QueryClient());

  return (
      ...
            <Authentication>
              <Layout>
                <Component {...pageProps} />
              </Layout>
            </Authentication>
      ...
  );
}

적용했더니 인증 로직을 처리하는 동안 보이는 하얀 화면이 마음에 들지 않았고 middleware를 이용하여 server side에서 처리하는 로직으로 바꾸었다.