Dynamic Routes
'/movies/all' 이라는 url을 만들고 싶다면?
그냥 '/movies' 라는 url을 만들고 싶다면?
* pages 폴더에 movies.js 파일을 생성해도 되지만 하위 url이 있을 경우 이게 더 깔끔
'/movies/123' 이런 식으로 url에 변수를 넣고 싶다면?
[pages/movies/[id].js]
import { useRouter } from "next/router";
export default function Detail() {
const router = useRouter();
console.log(router);
return <>detail</>;
}
이렇게 작성하고 콘솔에 찍힌 router를 살펴보면..
router의 query가 변수명: "url에 입력한 값" 으로 들어온다 !
Detail
Dynamic Routes를 활용해 데이터별로 상세 페이지를 만들어보자
[pages/index.js]
import Link from "next/link";
export default function Home(props) {
return (
...
{props.results.map((movie) => (
<Link href={`/movies/${movie.id}`} key={movie.id}>
<a>
<div className="movie">
...
</div>
</a>
</Link>
))}
map 내부를 Link로 감싸고 href에 map의 id 값을 넣어서 url을 이동할 수 있다
* 원래 Link(a 태그)에 div(flow content)를 넣으면 안되지만 HTML5부터는 가능하다
import { useRouter } from "next/router";
export default function Home(props) {
const router = useRouter();
return (
...
{props.results.map((movie) => (
<div
onClick={() => router.push(`/movies/${movie.id}`)}
className="movie"
key={movie.id}
>
...
</div>
))}
onClick 함수에 router.push를 넣어서 url을 이동할 수도 있다
onClick={() =>
router.push(
{
pathname: `/movies/${movie.id}`,
query: {
title: movie.original_title,
poster: movie.poster_path,
},
}
)
}
이때, query에 객체 형식으로 데이터를 함께 보낼 수 있다
onClick={() =>
router.push(
{
pathname: `/movies/${movie.id}`,
query: {
title: movie.original_title,
poster: movie.poster_path,
},
},
`/movies/${movie.id}`
)
}
이렇게 바로 url을 masking 해줄 수 있다
[pages/movies/[id].js]
import { useRouter } from "next/router";
export default function Detail() {
const router = useRouter();
return (
<div>
<h4>{router.query.title || "Loading..."}</h4>
<img src={`https:/image.tmdb.org/t/p/w500/${router.query.poster}`} />
</div>
);
}
router.query에서 데이터를 받아 사용할 수 있다
[pages/index.js]
<Link
href={{
pathname: `/movies/${movie.id}`,
query: {
title: movie.original_title,
poster: movie.poster_path,
},
}}
as={`/movies/${movie.id}`}
>
<a>
<h4>{movie.original_title}</h4>
</a>
</Link>
해당 방식은 Link의 href에서도 동일하다 !
다만 router.query를 받아오는 방식은 유저가 클릭을 통해 해당 페이지에 들어왔을 때만 유효하다
* 새로고침 하거나 url을 바로 타고 들어오는 경우를 대응하려면 결국 API를 받아와야 하지만, 받아오는 시간동안 router.query를 보여주는 의의가 있다
상세 데이터를 API 문서에서 확인하고
[next.config.js]
async rewrites() {
return [
{
source: "/api/movies",
destination: `https://api.themoviedb.org/3/movie/popular?api_key=${API_KEY}`,
},
{
source: "/api/movies/:id",
destination: `https://api.themoviedb.org/3/movie/:id?api_key=${API_KEY}`,
},
];
},
API Key를 포함하기 때문에 Rewrite로 masking 해주자
* source와 destination의 변수명이 같아야 한다
해당 데이터들도 상세 페이지에 바로 fetch하거나 getServerSideProps로 넣어주면 된다 !
본 내용은 노마드코더의 'NextJS 시작하기'를 바탕으로 작성되었습니다
'Front-end > Next.js' 카테고리의 다른 글
[TIL] Next.js & TypeScript & styled-components 초기 세팅 (0) | 2022.04.07 |
---|---|
[노마드코더] #7 Catch All, 404 (2) | 2022.02.24 |
[노마드코더] #5 Redirect & Rewrite, SSR (0) | 2022.02.19 |
[노마드코더] #4 Patterns, Fetching Data (0) | 2022.02.17 |
[노마드코더] #3 CSS, Custom App (2) | 2022.02.10 |