rhanziy

Next.js - router.isReady 본문

Next.js

Next.js - router.isReady

rhanziy 2024. 4. 11. 00:10
const onSubmit = handleSubmit((data) => {
    router.push({
      pathname: '/경로',
      query: { ...data },
    });
  });
  
  
const { query, ...router } = useRouter();
const methods = useForm<SearchSaleForm>({
  defaultValues: {
    productName: (query.productName as string) ?? undefined,
    storeName: (query.storeName as string) ?? undefined,
   },
});

검색버튼을 누르면 라우터 경로에 query를 붙여서 결과 리스트를 보여주는 페이지를 만들고있었다.

하지만 새로고침을 하면 url은 그대로인데 리스트 결과값이 전체로 보여지는 문제가 있었다.

저는 쿼리를 defaultValues로 박아줬는데 말이죵? ? 

 

router.isReady 메서드 사용하기

  • router에 있는 isReady를 판단하고, 준비가 안됐으면 null을 return하자. 이게 왠지 더 깔끔해보였다. useReady hook으로 만들어도 될 것 같군
const [isReady, _setIsReady] = useState(router.isReady);

  return (
    <>
      {isReady && 
      
      	// ...컴포넌트 작성
      
      }
    </>
  )

2024.05.22. 이하 문장 대삽질.  Next13에서 삭제된 기능,, ㅜㅜ 난 바보야

그러다 알게된 getServerSideProps

export async function getServerSideProps(context) {
  return {
    props: {}, // will be passed to the page component as props
  };
}
  • 페이지에서 getServerSideProps 함수를 export하는 경우 Next.js는 getServerSideProps가 반환하는 데이터를 사용하여 페이지를 pre-render한다.
  • 이때 함수는 페이지 요청마다 실행되고 함수가 반환하는 데이터는 페이지 컴포넌트의 props로 전달된다.
  • 서버 측에서만 실행되며 브라우저에서는 실행되지 않는다.

Next.js의 SSR은 미리 pre-rendering을 해놓고 유저가 해당 경로로 접근을 할 때 그 페이지를 제공해 주는 형태이다.
이때, 주목해야 할 점은, Next.js는 빌드 과정에서 이미 server폴더에 있는 html을 전달해줘야할지(SSR) 아니면 static 폴더에 있는 js 파일을 전달해줘야할지(CSR) 을 결정짓고 있다는 점이다.

 

즉, 페이지에서 서버측 렌더링이 필요한 경우 요청이 있을 때마다 서버에 의해 호출되는 getServerSideProps 함수를 작성하면 되는 줄 알았다. 그래서 사전렌더링을 통해 받아온 query를 useForm의 defaultValues로 값으로 넣어줘봤다.

const EventsPage: NextPage = ({
  searchQuery,
}: {
  searchQuery: InferGetServerSidePropsType<typeof getServerSideProps>;
}) => {
 
 // ...
  const methods = useForm<SearchEventProductForm>({
    defaultValues: searchQuery,
  });
 // ...

)}
  
  
export const getServerSideProps: GetServerSideProps = async (context) => {
  const searchQuery = context.query;
  return {
    props: { searchQuery },
  };
};

 

❗️ 여기서 잠깐~ getServerSideProp는 context 매개변수를 받아오는데, context에는 아래와 같은 데이터들이 담겨져 있다.

  • params:이 페이지가 동적 경로를 사용하는 경우 params에는 경로 매개 변수가 포함됩니다. 페이지 이름이 [id].js 인 경우 params는 {id : ...}와 같습니다.
  • req: HTTP IncomingMessage 객체이며 추가적인 쿠키 값인 문자열 키가있는 cookies 속성이 있습니다.
  • res: HTTP 응답 개체입니다.
  • query: 개체는 동적 경로 매개 변수를 포함한 쿼리 문자열을 나타냅니다.
  • preview: 미리보기 모드인 경우 true이고 그렇지 않으면 false입니다.
  • previewData: setPreviewData에 의해 설정된 미리보기 데이터입니다.
  • resolvedUrl: 클라이언트 전환에 대해 _next/data 접두사를 제거하고 원래 쿼리 값을 포함하는 요청 URL의 정규화 된 버전입니다.
  • locale은 활성 로케일 (활성화 된 경우)을 포함합니다.
  • locales는 모든 지원되는 로케일을 포함합니다 (활성화 된 경우).
  • defaultLocale은 구성된 기본 로케일 (활성화 된 경우)을 포함합니다.

 

결과적으로 새로고침을 했을 때, 정상적으로 원하는 검색결과의 리스트가 노출되긴했지만....사실 위에꺼 다 필요없다.

그냥 코드 그대로 이것만 넣어도 됨.

export async function getServerSideProps(context) {
  return {
    props: {}, // will be passed to the page component as props
  };
}

 

얘네도 영문을 몰라하는데ㅋ getServerSideProps를 작성만하면 pre-rendering이 실행돼서 라우터의 쿼리값이 정상적으로 defaultValues에 담겼나보다.

 

ㅠㅠ 운영에서 페이지 접속이 안돼서 다시 살펴봤는데, getServerSideProps는 Dynamic path일 경우에 사용하는 것 같다....

기존, getStaticProps때에는 미리 pre-rendering을 해서 html과 json을 만들어야 하는데 이 dynamic path에 무슨 값이 들어올지 확인이 정확히 안되므로 getStaticPaths 메소드를 사용해서 케이스 처리를 해줬었나보다.

getServerSideProps 함수는 CSR일지라도 매번 라우팅 이동을 할 때마다 서버에게 요청을 날려서 JSON데이터를 받아온다. 즉, 매번 새로운요청이 들어와서 getServerSideProps가 호출이 되므로, getStaticPaths와 같은 pre-rendering을 위한 작업이 필요하지 않다.
출처: https://velog.io/@chltjdrhd777/Next.js-Data-fetchinggetServerSideProps

아직 next.js에 대한 심도깊은 학습이 필요함을 느낀다.
getStaticProps 와 getStaticPaths를 통해 블로그 같은 cms컨텐츠들은 속도최적화를 할 수 있다고하니 이 부분도 추가로 공부해야겠다. 
참고할 블로그! https://byseop.com/post/@da66c257-ab86-4b2e-83c4-3fa455c21a3b


 

Comments