npx create-next-app@latest
npm install
프로젝트를 생성하면 pages
, public
, styles
폴더를 확인할 수 있다.
Next.js 앱은 일반 React 앱과 똑같이 public
폴더를 가지고 있으며, 이 폴더는 정적인 파일을 저장하는 데 사용된다. 하지만 일반 React 앱과는 다르게 Next.js 앱은 public
폴더에 index.html
파일이 없다.
Next.js는 서버 사이드 렌더링 기능을 제공하기 때문에, 서버에서 페이지를 렌더링하고, 이후 클라이언트에서 페이지를 JavaScript로 하이드레이션한다.
따라서 Next.js 앱은 public 폴더에 index.html
파일이 필요없는 것이다.
대신 pages
폴더 내부의 .js
파일을 통해 페이지를 정의하고,
필요한 정적 파일들은 public
폴더 내부에 저장하여 사용할 수 있다.
하이드레이션(Hydration)
: 서버 단에서 렌더링한 정적 페이지와 번들링된 JavaScript 파일을 클라이언트에게 보낸 뒤, 클라이언트 단에서 HTML 코드와 React인 JavaScript 코드를 서로 매칭시키는 과정
출처 - Next.js의 Hydrate란?
npm run dev
React 앱에서는 npm run start
명령어로 개발 서버를 실행했지만 Next.js 앱에서는 npm run dev
를 사용한다.
npm run start
: npm run build
로 생성된 빌드 파일을 사용하여 애플리케이션을 실행한다.npm run build
: Next.js 애플리케이션을 빌드한다.npm run dev
: Next.js 애플리케이션을 개발 환경에서 실행한다.pages
디렉토리 내에 .js
파일을 생성하면 해당 파일 이름으로 경로가 자동으로 라우팅된다.
pages/index.js
➡️ http://localhost:3000/
pages/news.js
➡️ http://localhost:3000/news
또한 디렉토리 안에 디렉토리를 생성하면 중첩 라우팅을 할 수 있다.
pages/news/index.js
➡️ http://localhost:3000/news
(pages/news.js
와 동일)pages/news/detail.js
➡️ http://localhost:3000/news/detail
pages/news/detail-page.js
➡️ http://localhost:3000/news/detail-page
동적 라우팅을 사용하고 싶다면 파일명에서 대괄호[]
안에 식별자를 추가하면 된다.
pages/news/[newsId].js
그리고 Next.js 훅인 useRouter
훅을 이용해 해당 페이지를 불러올 때 URL에 입력된 값(식별자)을 추출할 수 있다.
import React from 'react';
import { useRouter } from 'next/router';
function DetailPage() {
const router = useRouter();
const newsId = router.query.newsId;
// newsId를 이용해 해당 news 데이터를 백엔드 API에 요청할 수 있다.
return <div>DetailPage</div>;
}
export default DetailPage;
a
태그를 이용하면 브라우저가 서버에 새로운 요청을 보내고 새로운 HTML 페이지를 받아오기 때문에 새로고침이 일어나며 화면이 깜빡인다. (SPA X)Link
컴포넌트를 이용하면 새로운 HTML 페이지를 가져오지 않고 싱글 페이지 애플리케이션으로 유지할 수 있다.➡️ 클라이언트 사이드 렌더링 + 서버 사이드 렌더링 방식 결합의 장점!
고도로 상호작용하고 반응하며,
페이지의 상태(state)를 관리하고 저장할 수 있고,
사용자가 페이지를 이동할 때 완성된 HTML 파일을 볼 수 있고,
검색 엔진 또한 완성된 HTML 파일을 볼 수 있어 SEO에 유리하다.
Link
태그가 하는 일은 a
태그를 렌더링하고, 이 앵커 태그에 클릭이 발생하면 기본 동작인 새로운 HTML 페이지를 받아오는 요청을 보내지 못하도록 막는다. 대신 불러올 컴포넌트를 읽어들이고 URL을 변경하여 페이지가 바뀐 것처럼 보이게 한다. 따라서, 유저는 싱글 페이지 애플리케이션에 머무르는 것이다.
import React from 'react';
import { Fragment } from 'react';
import Link from 'next/link';
function NewsPage() {
return (
<Fragment>
<h1>The News Page</h1>
<ul>
<li>
<Link href='/news/page1'>page1</Link>
</li>
<li>
<a href='/news/page2'>page2</a>
</li>
</ul>
</Fragment>
);
}
export default NewsPage;
Public이 정적인 파일 담는 곳인지 몰랐는데 덕분에 알았습니다 ㅎㅎ 정리하는 방법이 인상적입니다!