Frontend/Next
[NextJS] NextJS 시작하기 - 7. 다이나믹 라우팅 & 페이지 이동
반응형
1. Routes
NextJS의 개요를 다루면서, pages
폴더에 대해 살펴본 적이 있지만, 오늘은 더 자세한 기능을 볼 것이다.
pages
는 페이지 라우팅을 자동으로 설정해주는 폴더로, 정적 라우팅은 물론 동적 라우팅도 가능하다.
아래 표를 통해 사용법을 확인하자.
pages 하위 폴더 구조 | URL |
pages/index.js | / |
pages/about.js | /about |
pages/movies/index.js | /movies |
pages/movies/all.js | /movies/all |
pages/movies/[id].js | /movies/12 |
동적 라우팅은 [변수].js
파일을 통해 설정할 수 있다.
pages/movies/[id].js
에서는 id
를 변수의 이름으로 설정한 것이고, useRouter를 통해 확인해 보면, query에 id
라는 이름의 객체가 있는 것을 볼 수 있다.
2. 페이지 이동하는 방법
페이지 간 이동하는 방법 두 가지를 살펴볼 것이다.
1) Link
- index.js 페이지의 영화 컨테이너를 Link로 감싼다.
- 하지만, 이는 HTML 구조에 반하는 것이다. (a 태그 안에는 텍스트가 들어가야 함)
<Link href={`/movies/${movie.id}`} key={movie.id}>
<a>
<div className='movie'>
<img
src={`https://image.tmdb.org/t/p/w500${movie.poster_path}`}
/>
<h4>{movie.original_title}</h4>
</div>
</a>
</Link>
2) router.push
- onClick 이벤트를 활용해 라우팅을 임의로 설정해준다.
- 이를 위해 useRouter의 push를 활용한다.
const router = useRouter();
const onClick = (id) => {
router.push(`/movies/${id}`);
};
return (
<div className='container'>
<Seo title='Home' />
{results?.map((movie) => (
<div
onClick={() => onClick(movie.id)}
className='movie'
key={movie.id}
>
...
</div>
))}
</div>
);
URL로 state를 넘기기
router.push에 영화 제목을 넘기고 싶으면 다음과 같이 작성하면 된다.
이 경우 유저가 wow라는 영화를 클릭하면 /movies/1212?title=wow 가 브라우저 URL로 넘어간다.
(단, 이렇게 state를 넘길 경우 직접 해당 페이지로 접근하고나 새로고침을 하는 경우 데이터가 존재하지 않아 정상적인 페이지가 보이지 않는다. 이에 대한 별도의 처리를 해줘야 한다)
const onClick = (id, title) => {
router.push(
{
pathname: `/movies/${id}`,
query: {
title,
},
},
);
};
브라우저의 URL을 마스킹하기
push는 다양한 옵션이 있다. 그증 as를 활용하면 브라우저의 URL을 마스킹할 수 있다.
위 경우 유저가 보는 URL에 쿼리가 담겨있었는데, 이를 원치 않을 경우 as를 사용해 숨기면 된다!
아래와 같이 push에 전달한 객체 다음 URL을 써주면 유저는 저 URL을 보게 된다. (/movies/1212)
const onClick = (id, title) => {
router.push(
{
pathname: `/movies/${id}`,
query: {
title,
},
},
`/movies/${id}`
);
};
최종 코드
import Link from 'next/link';
import { useRouter } from 'next/router';
import Seo from '../components/Seo';
export default function Home({ results }) {
const router = useRouter();
const onClick = (id, title) => {
router.push(
{
pathname: `/movies/${id}`,
query: {
title,
},
},
`/movies/${id}`
);
};
return (
<div className='container'>
<Seo title='Home' />
{results?.map((movie) => (
<div
onClick={() => onClick(movie.id, movie.original_title)}
className='movie'
key={movie.id}
>
<img src={`https://image.tmdb.org/t/p/w500`} />
<Link
href={{
pathname: `/movies/${movie.id}`,
query: {
title: movie.original_title,
},
}}
as={`/movies/${movie.id}`}
>
<a>
<h4>{movie.original_title}</h4>
</a>
</Link>
</div>
))}
</div>
);
}
반응형