Next.js 블로그 개발하기 - 4 (로딩 컴포넌트 구현)

오유진·2023년 4월 9일
0

로딩 컴포넌트 구현

  • Chakra UI를 이용하여 로딩 컴포넌트를 구현할것이다.
  • useMediaQuery 훅을 사용하여 모바일 화면에서는 로딩 아이콘을 오른쪽 상단, 데스크톱 화면에서는 오른쪽 하단에 보여주도록 구현한다.
  • 로딩 아이콘은 Spinner 컴포넌트를 사용하여 구현하였다.
  • zIndex를 99로 줘서 다른 컴포넌트들 보다 우선으로 보이게 해줘야한다.
//Loading.tsx
export default function Loading() {
  const [mobileView] = useMediaQuery("(max-width: 768px)", {
    ssr: true,
    fallback: false, // return false on the server, and re-evaluate on the client side
  });
  return (
    <>
      <Center w="100vw" h="100vh" zIndex={"99"} position={"fixed"}>
        {mobileView ? (
          <Center
            pos={"absolute"}
            top={10}
            right={10}
            bgColor={bgColor}
            padding={3}
            rounded={10}
          >
            <Spinner top={10} right={10} size={"md"} color={color} />
          </Center>
        ) : (
          <Center
            pos={"absolute"}
            bottom={10}
            right={10}
            bgColor={bgColor}
            padding={3}
            rounded={10}
          >
            <Spinner top={10} right={10} size={"md"} color={color} />
          </Center>
        )}
      </Center>
    </>
  );
}

로딩 컴포넌트 적용

Next.js 애플리케이션에서 로딩 컴포넌트를 구현하는 방법이다.

useEffect 훅을 사용하여 라우터 이벤트를 등록하고, 페이지 이동이 시작될 때 로딩 상태를 true로 변경한다. 이때, 로딩 컴포넌트를 렌더링하기 위해useState 훅을 사용한다.

const [loading, setLoading] = useState(false);
useEffect(() => {
  const showRoute = [
    "/",
    "/notes/:category",
    "/entry/:titleUrl/:id",
    "/guestbook",
  ];
  const start = (url: any) => {
    if (showRoute.find((route) => String(url).includes(route))) {
      setLoading(true);
    }
  };
  const end = (url: any) => {
    if (showRoute.find((route) => String(url).includes(route))) {
      setLoading(false);
    }
  };
  Router.events.on("routeChangeStart", start);
  Router.events.on("routeChangeComplete", end);
  Router.events.on("routeChangeError", end);
  return () => {
    Router.events.off("routeChangeStart", start);
    Router.events.off("routeChangeComplete", end);
    Router.events.off("routeChangeError", end);
  };
}, []);

위 코드에서 showRoute는 로딩 컴포넌트를 표시할 페이지 경로를 배열로 정의한다. Router.events.on() 메서드를 사용하여 라우터 이벤트에 대한 핸들러를 등록하고, 페이지 이동이 시작될 때 start() 함수가 실행된다. start() 함수는 showRoute에 포함된 경로 중 현재 페이지 경로가 포함되어 있으면 로딩 상태를 true로 변경한다. 페이지 이동이 완료되면 end() 함수가 실행되어 로딩 상태를 false로 변경한다.

마지막으로, 로딩 컴포넌트를 조건부 렌더링하여 로딩 상태가 true일 때만 보여주도록 한다.

//_app.tsx
return (
  <ChakraProvider theme={theme}>
    {loading && <Loading />}
    <RecoilRoot>
      <AnimatePresence
        initial={true}
        onExitComplete={() => window.scrollTo(0, 0)}
      >
        {mobileView ? <HeaderMobile /> : <Header />}
        <Component {...pageProps} />
        <Footer />
      </AnimatePresence>
    </RecoilRoot>
  </ChakraProvider>
);

위 코드에서 loading && <Loading />은 loading 상태가 true일 때만 로딩 컴포넌트를 렌더링한다.

완성

0개의 댓글