리액트에서는 react-router-dom을 이용하여 movies/:id 와 같은 형식으로 params를 지정해줄 수 있었는데 Next.js에서는 다른 방식으로 URL에 변수를 넣을 수 있다고 한다. 지금부터는 Next.js에서 라우터를 하는 방식을 알아보자.
Next.js에서 페이지 이동 - 페이지가 1개일 때
Next.js에서는 react-router-dom을 이용했을 때와는 다르게 Pages라는 폴더 안에 원하는 파일을 만들어주면 그게 자동으로 page의 URL이 되는 신기함을 경험했었다. 그런데 기본적인 URL을 만드는 방법은 알았지만 그 뒤에 params로 새로운 변수를 넣어주는 방법에 대해서는 알지 못해 이를 알아봐야겠다고 생각했다.
// 로컬 호스트 3000 뒤에 오는 기본적인 URL은 Pages 폴더 안의 파일명
http://localhost:3000/movies
http://localhost:3000/about
http://localhost:3000/home
Next.js에서 페이지 이동 - 페이지가 2개 이상일 때
리액트에서는 react-router-dom을 이용하여 movies/:id 와 같은 형식으로 params를 지정해줬다면 Next.js에서는 다른 방법을 이용한다. 여기서 내가 /movies 라는 경로 뒤에 all을 추가하고 싶다면, 실제 주소는 /movies/all 이 되어야한다. 이를 어떻게 적용할까?
// Pages 폴더 안에 movies라는 폴더를 만들고 그 안에 index.js와 all.js를 만들어준다.
// http://localhost:3000/movies/all
// Pages > movies > index.js & all.js
// index.js
export default function All() {
return (
<div>
<h1>movies index!</h1>
</div>
)
}
// all.js
export default function All() {
return (
<div>
<h1>ALL!</h1>
</div>
)
}
페이지가 하나밖에 없다면 그냥 Pages 폴더 안에 파일을 하나 생성해주면 되는 것이지만, 하나의 페이지 안에 또 다른 상세페이지가 있다면 폴더를 만들어서 그 안에 index.js와 원하는 경로 이름을 가진 파일을 넣어주면 된다. 즉, about의 경우 /about라는 경로를 하나만 가지지만 movies의 경우에는 /movies와 /movies/all 의 두가지 라우터를 사용할 수 있다.
Next.js에서 페이지 이동 - 상세페이지, URL에 변수 넣기
지금까지는 페이지를 이동시키는 방법에 대해 알아봤다면 지금부터는 페이지 이동시 보통 상세페이지에서 이동시키는 방식의 movies/movieID, 즉, URL에 영화 ID값을 넘겨주어 이동시키는 방법을 알아보려고 한다.
URL에 변수를 넣어주는 것도 생각보다 간단했다. movies라는 경로 뒤에 movieID를 각각 다르게 계속해서 넣어주고 싶다면 movies라는 폴더 아래에 대괄호를 열어 변수명을 입력해주면 되는 것이다. 그래서 나는 movies안에 [id].js라는 파일을 만들어주었다.
import { useRouter } from "next/router";
export default function Detail() {
const router = useRouter();
console.log(router)
return (
<div>
<h1>detail!</h1>
</div>
)
}
[id].js라는 파일을 만들어주고, http://localhost:3000/movies/1123132를 입력해줬더니 console에 이렇게 찍혔다. console 창을 열어 query 부분을 확인해보니 내가 입력한 id 값이 id라는 변수명으로 들어가있는 것을 확인할 수 있었다.
그렇게 이동시키는 방법을 영화 제목과 이미지를 클릭했을 때, 상세페이지로 이동이 되도록 적용시켜보자. 이미지를 클릭 했을 때는 onClick 함수를 이용하여, 영화 제목을 클릭했을 때는 Link 태그를 이용하여 이동시켰다.
import Seo from "../components/Seo";
import Link from 'next/link';
import { useRouter } from "next/router";
export default function Home({ results }) {
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}>
<img src={`https://image.tmdb.org/t/p/w500/${movie.poster_path}`} />
// Link 태그를 이용하여 이동시키는 방법
<h4><Link href={`/movies/${movie.id}`}><a>{movie.original_title}</a></Link></h4>
</div>
))}
<style jsx>{`
.container {
display: grid;
grid-template-columns: 1fr 1fr;
padding: 20px;
gap: 20px;
}
.movie img {
max-width: 100%;
border-radius: 12px;
transition: transform 0.2s ease-in-out;
box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 12px;
}
.movie:hover img {
transform: scale(1.05) translateY(-10px);
}
.movie h4 {
font-size: 18px;
text-align: center;
}
`}</style>
</div>
);
}
export async function getServerSideProps() {
const { results } = await (await fetch("http://localhost:3000/api/movies")).json();
return {
props: {
results,
}
}
}
이렇게 상세페이지로 이동시키는 방법을 알아보았는데 이 다음은 상세페이지 내에서 각각의 상세페이지 데이터를 가져오는 방법을 적용해보려고 한다.