https://www.inflearn.com/course/%ED%95%9C%EC%9E%85-%ED%81%AC%EA%B8%B0-nextjs?srsltid=AfmBOop98SToIvyP4ZLiwetJfX_FMn0dbu097kRsUWsuX9BOUxCY1Ihi
위 내용을 바탕으로 강의를 수강하며 정리하였습니다.
Next.js 13 버전에 새롭게 추가된 라우터
기존의 Page Router를 완전히 대체
변경된 사항
변경되지 않는 사항
vscode로 열기
vscode에서 .../onebite-next/ 폴더로 열기
터미널에서 section3 폴더 생성
vscode에서 터미널을 열어서 npx create-next-app@14 section03 명령어 실행
→ Ok to proceed에서 y 입력
→ 타입스크립트를 사용할 거냐는 질문에 Yes 선택 후 엔터
→ ESLint를 사용할 거냐는 질문에 Yes 선택 후 엔터
→ Tailwind CSS를 사용할 거냐는 질문에 No 선택 후 엔터
→ src/ 디렉토리를 사용할 거냐는 질문에 Yes 선택 후 엔터
→ App Router를 사용할 거냐는 질문에 Yes 선택 후 엔터
→ import alias를 사용할 거냐는 질문에 No 선택 후 엔터
import alias: 임포트 문을 사용할 때 절대 경로를 사용해서 값을 불러올 수 있게 하는 그러한 기능
npx 명령어create-next-app 명령어@14 명렁어개발 모드로 넥스트 앱 실행
생성된 /section03/ 폴더로 vscode에서 다시 열기
→ vscode의 터미널 열기
→ npm run dev 명령어 실행
→ http://localhost:3000/ 로 이동하면 확인 가능
→ (종료 시에는) Ctrl+D나 Ctrl+C 입력
.eslintrc.json 파일명을 eslint.config.mjs로 바꾸고 코드는 아래와 같이 수정하기
import { dirname } from "path";
import { fileURLToPath } from "url";
import { FlatCompat } from "@eslint/eslintrc";
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const compat = new FlatCompat({
baseDirectory: __dirname,
});
const eslintConfig = [
...compat.extends("next/core-web-vitals", "next/typescript"),
{
// 이 부분이 추가됩니다!
rules: {
"@typescript-eslint/no-unused-vars": "warn",
"@typescript-eslint/no-explicit-any": "off",
},
},
];
export default eslintConfig;
Page Router 버전의 페이지 라우팅과 방식이 크게 다르지 않음
→ 라우팅이 자동 설정된다는 점은 두 방식 모두 동일
Page Router 버전의 페이지 라우터에서는...
→ /src/pages/ 아래에 있는 파일명이나 폴더명이 페이지의 이름이 되었음
App Router 버전의 페이지 라우터에서는...
→ /src/app/ 아래에서 page.tsx라는 파일명을 갖는 파일만 페이지가 됨
→ 동적 경로는...
page 라우터에서 진행했던 '한입 북스 프로젝트'를 그대로 진행
vscode로 section03 폴더 열기
→ vscode 터미널을 열어서 npm run dev로 개발 모드 서버 열기
src/app/global.css 코드 전체 삭제
src/app/page.module.css 코드 전체 삭제
src/app/page.tsx 코드 수정
https://github.com/onebite-nextjs/vod__onebite-next-codes/blob/main/section03/chapter02/src/app/page.tsx
검색 페이지 생성: /src/app/search/page.tsx 코드 생성
https://github.com/onebite-nextjs/vod__onebite-next-codes/blob/main/section03/chapter02/src/app/search/page.tsx
- 쿼리 스트링을 위한 코드 추가
- 페이지에서 내보낼 내용 작성
하나의 도서 아이템을 상세히 조회하는 북페이지 생성: src/app/book/[id]/page.tsx 코드 생성
https://github.com/onebite-nextjs/vod__onebite-next-codes/blob/main/section03/chapter02/src/app/book/%5Bid%5D/page.tsx
- 동적 경로 라우팅을 설정할 때에는 이와 같이 설정하면 됨
- url 파라미터 값을 해당 페이지에서 활용하는 코드 추가
- 만약 url 파라미터 값을 여러 개 하고 싶다면 page router에서 실행한 것과 동일하게 /[id]/ 폴더명을 수정하면 됨
App Router에서는 쿼리 스트링이나 URL 파라미터와 같은 경로상에 포함되는 값들은 페이지 컴포넌트에게 모두 props로써 전달
서버 컴포넌트의 경우에는 서버 측에서 사전 렌더링을 위해 딱 한 번 실행이 되기 때문에 async 키워드를 붙일 수 있음
section03 폴더 열기npm run dev로 개발 모드 서버 열기/src/app/layout.tsx 코드 수정
https://github.com/onebite-nextjs/vod__onebite-next-codes/blob/main/section03/chapter03/src/app/layout.tsx
/src/app/(with-searchbar)/layout.tsx 코드 생성
https://github.com/onebite-nextjs/vod__onebite-next-codes/blob/main/section03/chapter03/src/app/(with-searchbar)/layout.tsx
/src/app/page.module.css 파일과 /src/app/page.tsx 파일을 /src/app/(with-searchbar)/ 폴더 내로 이동
/src/app/layout.tsx
layout.tsx 코드에서는 page/tsx가 어디 위치에 배치할 지 명시해줘야 함!!
→ layout.tsx 코드에서 {children}이라는 프롭스를 꼭 전달 받아야 함
특정 페이지들에만 적용되는 공통 레이아웃 적용을 위해서는 라우트 그룹(Route Group) 기능 사용 가능
→ /src/app/ 폴더 밑에 새로운 폴더를 생성하는데, 이때 폴더의 이름은 ()로 감싸주기
→ 라우트 그룹은 경로 상에는 아무런 영향을 미치지 않음
상호작용이 있는 컴포넌트와 상호작용이 없는 컴포넌트가 섞여 있을 때, 상호작용이 있는 컴포넌트만 수화(Hydration)하면 되는데...
Page Router에서는 한 페이지에 속해있기만 한다면 상호작용 여부와 상관 없이 Hydration을 전부 진행해서 TTI까지 늦어지게 됨
그렇다면?
상호작용이 없는 컴포넌트들은 Hydration이 필요가 없기 때문에, 상호작용이 있는 컴포넌트만 구분해서 Hydration을 진행하면 됨
상호작용이 없는 컴포넌트들은 사전 렌더링 때 한 번만 불러오면 됨
▼ 사전 렌더링 시에는 모든 컴포넌트를 불러옴
▼ 수화를 위해 컴포넌트를 불러올 때에는, 상호작용이 있는 컴포넌트들만 구분해서 불러옴
=> Next.js의 공식 문서에서는 페이지의 대부분은 서버 컴포넌트로 구성할 것을 권장하며, 클라이언트 컴포넌트는 꼭 필요한 경우에만 사용할 것
section03 폴더 열기npm run dev로 개발 모드 서버 열기/src/app/(with-searchbar)/searchbar.tsx 코드 생성App Router에서는 기본적으로 모든 컴포넌트가 서버 컴포넌트로 동작
서버 컴포넌트에서는 원래 서버에서 할 수 있었던 보안에 민감한 작업들이나 데이터를 패칭해 오는 기능 등의 다양한 작업들을 진행할 수 있게 됨
= 클라이언트 컴포넌트에서는 해당 동작이 불가능
= 클라이언트 컴포넌트에서는 가능한 동작을 서버 컴포넌트에서는 동작 불가능 (Ex. useEffect())
링크는 HTMl의 고유 기능이기 때문에 JS 기능을 활용하는 상호작용은 아니어서, 링크로 이동하는 기능만 포함되어 있다면 해당 컴포넌트는 서버 컴포넌트!
▼ 불가능!

▼ 불가능!
▼ 왜 불가능하지?
▼ 그럼 이런 경우에서 Next.js는 어떻게 동작하지?
src/app/(with-searchbar)/client-component.tsx 코드 생성
https://github.com/onebite-nextjs/vod__onebite-next-codes/blob/main/section03/chapter05/app/(with-searchbar)/client-component.tsx
src/app/(with-searchbar)/server-component.tsx 코드 생성
https://github.com/onebite-nextjs/vod__onebite-next-codes/blob/main/section03/chapter05/app/(with-searchbar)/server-component.tsx
src/app/(with-searchbar)/page.tsx 코드 수정
https://github.com/onebite-nextjs/vod__onebite-next-codes/blob/main/section03/chapter05/app/(with-searchbar)/page.tsx
만약 어쩔 수 없이 클라이언트 컴포넌트가 서버 컴포넌트를 반드시 자식으로 둬야 하는 경우가 된다면, 그럴 때에는 서버 컴포넌트를 클라이언트 컴포넌트에서 children props로 받아서 렌더링을 시켜주기
직렬화(Serialization)

그런데, JS 함수는 직렬화가 불가능
= 서버 컴포넌트에서 클라이언트 컴포넌트로 향하는 Props가 될 수 없음
사전 렌더링 과정 진행 중에...
RSC Payload
- React Server Component의 순수한 데이터(결과물)
- React Server Component를 직렬화 한 결과
- RSC Payload에는 서버 컴포넌트의 모든 데이터가 포함
- 서버 컴포넌트의 렌더링 결과
- 연결된 클라이언트 컴포넌트의 위치
- 클라이언트 컴포넌트에게 전달하는 Props 값
- 예시
실습 부분만 다시 듣기
네비게이팅(Navigating)
= 페이지 이동을 의미
페이지 이동은 Client Side Rendering 방식으로 처리
= Page Router 버전과 동일한 방식
App Router에서는 Server Component가 추가되어 방식이 살짝 변경됨 (비슷하긴 하지만...)
section03 폴더 열기npm run dev로 개발 모드 서버 열기모든 페이지에 다 똑같이 렌더링 되는 글로벌 내비게이션 바 생성
→ 루트 레이아웃에 생성하면 됨
/src/app/layout.tsx 코드 수정
https://github.com/onebite-nextjs/vod__onebite-next-codes/blob/main/section03/chapter06/src/app/layout.tsx
/src/app/(with-searchbar)/search/page.tsx 코드 수정
https://github.com/onebite-nextjs/vod__onebite-next-codes/blob/main/section03/chapter06/src/app/(with-searchbar)/search/page.tsx
/src/app/(with-searchbar)/page.tsx 코드 수정
https://github.com/onebite-nextjs/vod__onebite-next-codes/blob/main/section03/chapter06/src/app/(with-searchbar)/page.tsx
/src/omponents/ 폴더 생성 후 client-component.tsx, server-components.tsx, serachbar.tsx 코드를 해당 폴더로 이동
/src/components/searchbar.tsx 코드 수정
https://github.com/onebite-nextjs/vod__onebite-next-codes/blob/main/section03/chapter06/src/components/searchbar.tsx
수업 자료로 올려주신 /src/ 코드를 바탕으로 코드 리뷰 진행
코드 리뷰 필요하면 다시 듣기