간략하게 프로젝트의 폴더 구조를 살펴보겠습니다.
처음 Next.js 프로젝트를 생성하게 되면 하위 폴더로 pages,public,styles가 생성된 것을 볼 수 있는데요.
먼저 public에는 index.html이 없습니다. 이전 글에서도 언급을 했습니다. Next.js 는 SSR이기 때문에 index.html을 파일로 관리하지 않습니다. 속이 텅텅 빈 index.html을 전송하지 않고 서버에서 미리 랜더링을 마친 뒤 파일을 전송하기 때문입니다.
그리고 Next.js는 file-base routing을 지원하기 때문에 pages는 중요한 폴더입니다. 라우팅을 파일을 기반으로 할 수 있기때문에 매우 편리하다고 할 수 있습니다. (처음 프로젝트를 생성했을때 _app.js가 있는데 지금 자세한 설명은 스킵하도록 하겠습니다.)
styles에는 스타일을 담당하는 css 파일을 관리할 수 있습니다.
파일 베이스 라우팅을 해보도록 하겠습니다.
도메인.com/
로 라우팅 하기 위해서는 index.js를,
도메인.com/news
로 라우팅하기 위해서는 news.js를 만들면 됩니다.
pages 아래에 index.js(기본 라우팅 주소)를 만들고
function HomePage() {
return (
<div>
<h1>홈페이지</h1>
</div>
);
}
export default HomePage;
news.js를 만들고
function news() {
return (
<div>
<h1>뉴스 페이지</h1>
</div>
);
}
export default news;
위와 같이 함수형 컴포넌트를 작성해주면 되겠습니다.
Next js 에서는 import React from "react";
를 생략해주어도 되도록 모던화 되어있습니다.
그리고 npm run dev로 프로젝트를 실행해서 localhost:3000
와 localhost:3000/news
로 접속하면 각 페이지를 확인할 수 있습니다.
만약 도메인주소.com/news/detail
과 같이 라우팅을 하고싶다면 어떻게 해야할까요?
간단하게 pages 폴더 하위에 news 폴더를 만들어주면됩니다.
그리고 news 폴더 안에 detail.js 파일을 추가해주면 됩니다. (index.js도 물론 됩니다.)
도메인주소.com/news/1번
도메인주소.com/news/2번
위와 같이news/[파라미터값]
뒤에 값을 파라미터로 받고 싶을때는 어떻게 해야할까요?
news폴더 내부 파일명을 [poostId].js
로 해주면 됩니다.
import { useRouter } from "next/router";
function DetailPage() {
const router = useRouter();
const newsId = router.query.newsId;
return (
<div>
<h1>뉴스 디테일</h1>
</div>
);
}
export default DetailPage;
Next js는 Parameter Values를 가져올 수 있도록 우리에게 특별한 Hook(useRouter)을 사용할 수 있게 해줍니다.
이 useRouter Hook은 NextJS팀에 의해서 만들어진 것입니다.
일반 HTML에서는 <a>
태그로 링크를 걸어주는게 일반적입니다. 하지만 <a>
태그로 링크를 걸어주게 되면 페이지 이동간에 새로고침(refresh)이 발생하게 됩니다. 즉 서버로 부터 정보를 받아 새로 랜더링하게 되는 것입니다.
이렇게 되면 SPA 의 장점이 의미없어 지게 되고 사용자 경험도 좋지 못합니다. (또한 state 값을 잃게된다.)
SPA에 계속해서 머무르기 위해서는 Link
를 사용해야합니다.
import Link from "next/link";
이 Link
컴포넌트는 <a>
태그로 렌더링 되지만 Next.js가 이 태그를 감지하기 때문에 새로운 HTML을 서버에 요청하지 않도록 방지해줍니다. 그리고 이미 로딩된 컴포넌트를 로딩해주고 URL을 변경해주어서 사용자는 페이지가 이동된 것 처럼 느끼게 된다. 새로고침은 발생하지 않게 됩니다.
import { Fragment } from "react";
import Link from "next/link";
function news() {
return (
<Fragment>
<h1>뉴스 페이지 in news 폴더</h1>
<ul>
<li>
<Link href="news/Next JS is Great.">Next JS는 좋아</Link>
</li>
<li>나는 최고야</li>
</ul>
</Fragment>
);
}
export default news;