혼자 적어보는 노트

[Next.js] 페이지 이동 시 로딩 본문

NextJS

[Next.js] 페이지 이동 시 로딩

jinist 2022. 8. 19. 04:10

 

next로 프로젝트를 진행하며 일부 페이지에 ssr을 적용했는데,

해당 페이지에 접근하려고 링크를 클릭하면 약간의 딜레이 후에

페이지가 이동되어 조금 이질감이 느껴졌다.

 

 

router.event를 사용한 로딩 처리

 

next의 router에서 제공하는 이벤트를 사용하여

route가 변경될 때를 감지하여 loading 페이지를 보여주는 방식을 사용할 수 있다.

 

_app.tsx

function MyApp({ Component, pageProps }: AppPropsWidthLayout) {
    const [loading, setLoading] = useState(false);

    useEffect(() => {
    const start = (url: string) => {
      setLoading(true);
    };
    
    const end = () => {
      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);
    };
  }, []);
  
  const getLayout = Component.getLayout || ((page) => <Layout>{page}</Layout>);

  return (
    <>
      <AppHead />
      <RecoilRoot>{getLayout(loading ? <Spinner /> : <Component {...pageProps} />)}</RecoilRoot>
    </>
  );
}

 

 

📌문제사항 

위 코드로 웬만하면 작동이 되겠지만 현재 프로젝트의 일부 페이지에 router.replace를 사용하여

query를 변경하는 부분이 꽤 있었는데, replace를 사용하는 것은 route가 change되는 것으로 인식하기 때문에
useEffect를 통해 route가 변경되는 페이지에 접근하면 무한 렌더링이 발생하는 결과가 나타났다.

 

✅ 해결

replace를 하는 곳에서 shallow 옵션을 통해 얕은 라우팅을 설정할 수 있는데, shallow:true를 설정해놓고 

routeChangeStart()가 실행될 때 내부에서 shallow 옵션을 확인하여 loading이 나타나도록 했다.

const start = (url: string, { shallow }: { shallow: boolean }) => {
  if (!shallow) {
    setLoading(true);
  }
};

const end = () => {
  setLoading(false);
};

//..생략

 

동작이 잘 되는 것을 확인하고 위의 코드를 조합하여 hooks로 만들어서 사용했다.

const { loading } = useRouteChange();

 

 

 

 

 

참고 블로그

Comments