Page Router
- pages 폴더의 구조를 기반으로 페이지 라우팅을 제공
- Dynamic Routes(동적 경로): 페이지에서 연결되는 페이지. [id].js
ex) ~/item/100
- Pages/_app.tsx: React의 App Component와 같은 역할. 모든 Component의 부모 Component.
모든 요소의 공통되는 요소는 App Component에 넣어주면 된다!
export default function App({ Component, pageProps }: AppProps) {
return <>
<header>글로벌 헤더</header>
<Component {...pageProps} />
</>;
}
- pages/_document.tsx: 모든 페이지에 공통으로 들어가야하는 HTML코드를 설정. React의 'index.html'와 같다.
Pages 폴더구조
- book/[id].tsx = ~/book/{id}
- Catch All Segment: 모든 구간에 대응하는 페이지([...id].tsx 같은 방식으로 작성)
- Optional Catch All Segment: index.tsx 파일이 없기 때문에 ~/book 경로는 오류가 나지만, [[...id]].tsx 로 파일 이름을 작성해주면 완전히 범용적인 파일이 된다.
Page Router의 단점
- 페이지별 레이아웃 설정이 번거롭다.
- 데이터 페칭이 페이지 컴포넌트에 집중된다.
- 불필요한 컴포넌트들도 JS Bundle에 포함된다.
Navigating
- 페이지를 이동할 때 a태그보다 빠른 방법
- Link Component를 사용
<Link href={"/"}>index</Link>
<Link href={"/search"}>search</Link>
<Link href={"/book/1"}>book/1</Link>
- Programmatic Navigating(프로그래매틱한 페이지 이동): 사용자가 클릭해서 이동하는 것이 아닌, 특정 버튼이 클릭 되었거나 특정 조건이 만족되었을 때 함수 내부에서 페이지 이동
const router = useRouter();
const onClickButton = () => {
router.push('/test');
};
(...)
<button onClick={onClickButton}>/test 페이지로 이동</button>
- router.replace(): 뒤로가기를 방지하며 페이지 이동.
- router.back(): 페이지를 뒤로 이동.
Pre-Fetching
- 페이지를 사전에 불러온다는 뜻.
- 현재 사용자가 보고있는 페이지에서 이동할 가능성이 있는 모든 페이지를 미리 불러온다.
- 페이지 이동이 빨라진다는 장점이 있다!
- 개발 환경에서는 확인이 어렵고, npm run build 후 npm run start로 실행.
- Network 탭에서 확인이 가능하다.
- Link Component로 페이지 이동시 적용된다.
- Programmatic Navigating 에서도 적용을 원할 경우, useEffect로 가능하다.
useEffect(() => {
router.prefetch('/test');
}, []);
- pre-Fetching을 원하지 않을 경우, props로 처리가 가능하다.
<Link href={"/search"} prefetch={false}>search</Link>
API Routes
- Next.js에서 API를 구축할 수 있게 해주는 기능
- api 폴더 내에 .ts 파일로 작성한다.
Data-fetching
Reacp App 에서의 데이터 페칭
- 불러온 데이터를 보관할 State 생성
- 데이터 페칭 함수 생성
- 컴포넌트 마운트 시점에 fetchData 호출
- 데이터 로딩중일때의 예외 처리
export default function Page() {
const [state, setState] = useState();
const fetchData = async () => {
const response = await fetch("...");
const data = await response.json();
setState(data);
};
useEffect(() => {
fetchData();
}, []);
}
if (!state)return "Loading...";
Next.js의 다양한 사전 렌더링
- 서버사이드 렌더링(SSR)
- 가장 기본적인 사전 렌더링 방식
- 요청이 들어올 때마다 사전 렌더링을 진행함
export const getServerSideProps = async () => {
const [allBooks, recoBooks] = await Promise.all([
fetchBooks(),
fetchRandomBooks(),
]);
return {
props: {
allBooks,
recoBooks,
},
};
};
export default function Home({
allBooks,
recoBooks,
}: InferGetServerSidePropsType<typeof getServerSideProps>)
- 정적 사이트 생성(SSG)
- 빌드 타임에 미리 페이지를 사전 렌더링 해둠
- 매번 똑같은 페이지만 응답함, 최신 데이터 반영은 어렵다
- 개발모드에서는 확인이 어렵다.
export const getStaticProps = async () => {
const [allBooks, recoBooks] = await Promise.all([
fetchBooks(),
fetchRandomBooks(),
]);
return {
props: {
allBooks,
recoBooks,
},
};
};
export default function Home({
allBooks,
recoBooks,
}: InferGetStaticPropsType<typeof getStaticProps>)
- 기존에 틀은 있지만 데이터가 계속해서 바뀌는 페이지를 SSR 방식으로 렌더링을 하게 될 경우
export const getStaticPaths = () => {
return {
paths: [
{params: { id : "1" }},
{params: { id : "2" }},
{params: { id : "3" }},
],
fallback: true,
// false: 404 notFound
// blocking: SSR 방식
// true: SSR 방식 + 데이터가 없는 fallback 상태의 페이지부터 반환
};
};
- 증분 정적 재생성(ISR)
- SSG 방식으로 생성된 정적 페이지를 일정 시간을 주기로 다시 생성하는 기술
return {
props: {
allBooks,
recoBooks,
},
revalidate: 3,
};
- 사용자의 action으로 페이지의 변동이 있는 경우, ISR로 처리하기에 어려움이 있다. 따라서, 요청을 기반으로 페이지를 재생성하는 On-Demand ISR을 사용한다.