ClientSide에서 rendering 전 redirect 가능한가?

2022. 10. 6. 14:42Web_Programming/Next

+ 해당 포스팅은 next@12.x 버전의 내용입니다.

 

Next js에서 URL 파라미터의 유효성을 검사하여 리디렉션 시키는 과정에서 고민이 생겨 간단하게 포스팅을 남겨보려 합니다.

요구사항은 페이지가 렌더되기 전에 유효성을 검사하여 /404 로 리디렉션 시켜라 였습니다.

Next js의 SSR을 이용하면 쉽게 getServerSideProps 함수를 이용하여 렌더 전에 서버에서 검사하여 redirect 시킬 수 있었습니다.

 

그렇다면 서버사이드가 아닌 클라이언트 단에서 렌더 전에 redirect 시킬 수 있을까?

에 대한 질문에 바로 대답을 못하는 것을 느끼고 next의 렌더링 과정에 대한 이해가 부족하다 생각했고 공부해보게 되었습니다.


단순하게 클라이언트에서 useRouter로 redirect 시킨다면?
const router = useRouter();
const {page} = router.query;

if(/*유효성 검사*/){
	router.replace("/404");
}

return (<></>);

router instance를 찾을 수 없다며 오류가 납니다.

 

제공 내용으로 보면 push, replace, back 과 같은 router 이동 함수는 useEffect를 이용하여 렌더링 이후 시점에 호출해야 한다고 나와있습니다.

정확한 이유를 파악하고자 next 렌더링 과정을 다시 살펴봤는데요.

 

https://nextjs.org/docs/messages/no-router-instance

 

no-router-instance | Next.js

No Router Instance During Pre-rendering (SSR or SSG) you tried to access a router method push, replace, back, which is not supported. In a function Component you can move the code into the useEffect hook. In a class Component, move any calls to router meth

nextjs.org


Next의 pre-rendering

[initial Load] : 정적 페이지 render ⇒ [hydration] JS 코드 매칭 [컴포넌트 초기화]

위와 같은 과정으로 Next는 서버에서 먼저 데이터 변경에 영향이 없는 정적 HTML을 가져와 render 시키고

이후에 hydration 이라는 과정으로 JS 파일을 연결하여 컴포넌트를 초기화해줍니다.

 

hydration 완료 이전에 router의 함수를 호출하여 오류가 발생하는 것이 아닌가라고 생각하게 되었습니다.

 

또한 이 과정을 CSR로 수행하면 어떻게 되는지 테스트해봤습니다.

CSR

모두 브라우저 단에서 처리된다.

DOM 생성 ⇒ JS 수행 ⇒ 렌더

next dynamic 메소드를 이용하여 ssr 옵션을 false로 하고 csr로만 동작시켜보았습니다.

const ResultPhase = dynamic(
  () =>
    import("components/Scenarios/dockingCalculation/___templates/ResultPhase"), // Component로 사용할 항목을 import합니다.
  { ssr: false }, // ssr옵션을 false로 설정해줍니다.
);

 

수행해보면 렌더링 전에 router.replace 함수가 수행은 되지만 비동기로 처리되어

마운트 되기 전까지 pending 되었다가 수행되더라고요.

왜 이렇게 마운트 이후에만 수행 가능한가는 공부가 조금 더 필요할 듯합니다.

이후에 알게 되면 포스팅을 보완하겠습니다-

 

결론은 렌더링 전에 리다이렉트 시키기 위해서는 서버사이드를 이용해야 한다가 되는 것 같아요.

 

방법을 찾아보면서 덕분에 ssr, csr 과정을 깊게 알게 되었고, router 동작을 살펴볼 수 있었습니다.

 

불가능하기에 명확한 해답을 얻지 못한 것인지 제가 다른 방법을 발견하지 못한 것인지 아시는 분이 계시다면 댓글 남겨주시면 감사하겠습니다!

이외에 제가 생각한 부분에 잘못된 부분이 있다면 알려주세요!

반응형