[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를 사용하면, 이는 클라이언트 사이드(프론트)에서만 실행된다.