본문 바로가기

Frontend/Next

[NextJS] NextJS 시작하기 - 8. URL에 데이터 전달하고 가져오기(Catch All URL)

반응형

1. 모든 URL 잡기

pages 하위에 파일명을 [...params].js(원하는 이름 사용)와 같이 설정하면 어떤 URL이라도 잡을 수 있다.

이를 이용해 영화 제목을 URL에 넣고, URL에서 정보를 받아 About 페이지에 뿌려줄 것이다. 

 

1. pages/movies/[id].js를 pages/movies/[...params].js로 수정하고

2. index.js에서 페이지 이동 부분을 수정한다.

const onClick = (id, title) => {
	router.push(`/movies/${title}/${id}`);
};
<Link href={`/movies/${movie.original_title}/${movie.id}`}>
    <a>
      <h4>{movie.original_title}</h4>
    </a>
</Link>

 

이때, 홈에서 영화 하나를 클릭하면, 디테일 페이지의 URL은 /movies/Sing%202/438695와 같고, 

router를 콘솔에 찍어보면 params배열 형식을 갖는 것을 확인할 수 있다.

 

[...params].js

ES6 문법을 사용해 router.query.params의 값을 아래와 같이 가져올 수 있고, 바로 화면에 뿌릴 수 있다.

import { useRouter } from 'next/router';

export default function Detail() {
  const router = useRouter();
  const [title, id] = router.query.params;
  return (
    <div>
      <h4>{title}</h4>
    </div>
  );
}

 

2. 시크릿 창에서 직접 접속하거나 새로고침 하는 경우 에러 발생

위 코드에서 router.query.params을 통해 값을 가져오는 것은 Home에서 클릭을 통해 About페이지로 넘어올 때는 아무런 문제가 없다. (서버에서 params가 pre-rendering 되고 이 값을 그대로 넘겨주기 때문)

 

하지만.. 

시크릿 창에서 About URL을 입력해 직접 접속하거나, About창에서 새로고침을 하는 경우 

🔒 라우팅 과정(페이지 접근 과정)이 달라져(클라이언트에 데이터가 없어), 서버에서는 router.query.params가 배열 형태로 존재하지 않는다. 즉, 해당 문법을 사용할 수 없기 때문에 에러가 발생한다.

 

이를 해결하기 위한 두 가지 방법은 다음과 같다.

🔑 S1. 배열 초기화 상태를 마련한다. -> 클라이언트에서 처리

import { useRouter } from 'next/router';

export default function Detail() {
  const router = useRouter();
  const [title, id] = router.query.params || [];
  return (
    <div>
      <h4>{title}</h4>
    </div>
  );
}

 

🔑 S2. getServerSideProps를 통해 pre-rendering 되도록 한다. -> 서버에서 처리

  • SEO 최적화를 해야 할 때 사용
  • 유저에게 로딩을 절대로 보여주고 싶지 않을 때 사용
export default function Detail({ params }) {
  const [title, id] = params;
  return (
    <div>
      <h4>{title}</h4>
    </div>
  );
}

export function getServerSideProps({ params: { params } }) {
  return {
    props: {
      params,
    },
  };
}

 

정리: 컴포넌트 내부에서 router를 사용하면, 이는 클라이언트 사이드(프론트)에서만 실행된다.

 

 

반응형