-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[서준환] 11장: Next.js 13과 리액트 18 #85
The head ref may contain hidden characters: "11\uC7A5/\uC11C\uC900\uD658"
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
# 11장 Next.js 13과 리액트 18 | ||
|
||
## 11.1 app 디렉터리의 등장 | ||
|
||
기존 pages 기반 라우팅에서는 레이아웃과 같은 처리를 하기 위해선 해당 페이지에 직접적으로 해야만 했다. | ||
혹은 공통으로 적용되게끔 \_app에서 처리를 할 수 있었다. | ||
이러한 방식은 각기 다른 페이지에서 다른 레이아웃을 적용하기에는 한계가 있었다. | ||
|
||
### 11.1.1 라우팅 | ||
|
||
기존 pages 기반 라우팅에서는 라우팅을 위한 파일을 pages 디렉터리에 생성했다. | ||
app 디렉터리는 app폴더 내부의 미리 정의한 특정 컨벤션을 갖는 파일을 자동으로 라우팅한다. | ||
|
||
#### 라우팅 정의 | ||
|
||
app 디렉터리 하위의 폴더를 생성하면 해당 폴더가 라우팅 경로로 등록된다. | ||
만약 페이지를 보여주고 싶다면 해당 폴더 내부에 page.tsx를 생성하면 된다. | ||
더불어 해당 파일 내부의 컴포넌트 함수는 `export default`로 내보내야 한다. | ||
|
||
#### layout | ||
|
||
app 디렉터리 내부에 layout 디렉터리를 생성하고 그 안에 layout.tsx를 생성한다. | ||
이렇게 하면 해당 layout.tsx는 app 디렉터리 내부의 모든 페이지에 적용된다. | ||
루트에도 layout.tsx를 생성하면 모든 페이지에 적용되며 기존 pages 기반 라우팅에서의 \_app, \_document와 같은 역할을 한다. | ||
|
||
#### page | ||
|
||
page는 앞에서 구성했던 layout을 기반으로 페이지를 구성한다. | ||
page가 받는 props는 아래와 같다. | ||
|
||
- children: 페이지 컨텐츠 | ||
- params?: 라우팅 경로의 파라미터 ex) /user/[id]/page.tsx의 경우 {id: string) | ||
- searchParams?: 쿼리스트링 파라미터 | ||
|
||
`searchParams`는 `layout`에서 가져올 수 없어서 해당 값에 의존적이라면 `page`에서 처리해야 한다. | ||
> layout은 페이지 탐색 중 리렌더링을 하지 않기에 `searchParams`를 가져올 수 없다. | ||
|
||
#### error | ||
|
||
error는 해당 라우팅 영역 안에서 error가 발생했을 때 처리할 수 있는 페이지이다. | ||
error.tsx를 생성하면 해당 페이지가 error가 발생했을 때 보여진다. | ||
`layout`에서 에러가 발생한다면 같은 레벨의 error를 보여주진 않기에 상위 레벨의 error나 global error를 통해 처리해야 한다. | ||
|
||
#### not-found | ||
|
||
not-found는 해당 라우팅 영역 안에서 페이지를 찾을 수 없을 때 보여진다. | ||
|
||
#### loading | ||
react의 suspense와 같은 역할을 한다. | ||
app 디렉토리에선 컴포넌트나 페이지에서 직접적으로 비동기 호출이 가능하기에, 해당 페이지에서 비동기 호출을 할 때 loading을 보여주기 위해 사용한다. | ||
|
||
#### route | ||
|
||
route는 기존 pages/api와 같은 역할을 한다. | ||
app 디렉터리 내부에 route 디렉터리를 생성하고 그 안에 route.ts를 생성한다. | ||
pages 기반에선 api 폴더에 몰아서 놔둬야 했었는데, app 디렉터리에선 라우팅과 같은 위치에 놔둘 수 있다. | ||
but! pages와 함께 둔다면 에러가 발생한다. | ||
|
||
## 11.2 리액트 서버 컴포넌트 | ||
|
||
서버 컴포넌트 !== 서버 사이드 렌더링 | ||
|
||
### 11.2.1 기존 리액트 컴포넌트와 서버 사이드 렌더링의 한계 | ||
|
||
기존 리액트 컴포넌트의 한계는 아래와 같다. | ||
|
||
- 번들 사이즈가 0인 컴포넌트를 만들 수 없다. | ||
- hydrate를 하기 위해 클라이언트에서는 똑같은 번들이 필요하다. | ||
- 백엔드 리소스의 직접적인 접근이 불가하다. | ||
- 만약 가능해진다면 불필요한다 보일러 플레이트를 줄일 수 있다. | ||
- 자동 코드 분할이 어렵다. | ||
- 연쇄적으로 발생하는 클라이언트와 서버의 요청을 대응하기 어렵다. | ||
- a컴포넌트의 데이터를 가져오기 위해 b컴포넌트의 데이터를 가져와야 한다면 불필요하게 많은 요청이 발생한다. | ||
|
||
> 궁금증 | ||
> 마지막 연쇄적으로 발생하는 클라이언트와 서버의 요청 대응이 어렵다는 것은 react-query와 같은 라이브러리를 통해 어느정도 해결이 된 것인가요? | ||
> 서버 컴포넌트는 한 번의 렌더링 동안 요청한 것들을 캐싱하여 해당 렌더링 사이클 중 다른 컴포넌트에서 동일 리소스를 요청했을 때 캐싱된 데이터를 사용하여 처리한다고 하던데, 이것이 react-query와 같은 라이브러리와 같은 역할을 하는 것인가요? | ||
> 음 뒤에 나오는군요,,! | ||
|
||
### 11.2.2 서버 컴포넌트란? | ||
|
||
하나의 **언어**, 하나의 **프레임워크**로 **서버**와 **클라이언트**를 모두 다루는 것이 서버 컴포넌트이다. | ||
컴포넌트 트리에서 클라이언트 컴포넌트와 서버 컴포넌트가 혼재될 수 있는데, 이는 ReactNode를 잘 사용해야 한다.? | ||
서버 컴포넌트의 특징은 아래와 같다. | ||
|
||
- 요청이 오면 그 순간 서버에서 딱 한 번 실행된다. | ||
- 렌더링 생명주기를 사용할 수 없다. | ||
- 서버에서 실행되니 DOM API, window, document 등을 사용할 수 없다. | ||
- 데이터베이스, 파일 시스템 등 서버에만 있는 데이터를 비동기로 접근할 수 있다. | ||
클라이언트 컴포넌트의 특징은 아래와 같다. | ||
- 브라우저에서 실행되니 서버 컴포넌트를 불러오거나 서버 전용 유틸리티를 사용할 수 없다. | ||
- but! 자식 요소로 서버 컴포넌트를 가질 수 있다. | ||
- how? 실제 브라우저에 렌더링 될 때 이미 서버 컴포넌트는 렌더링이 완료되어 있기에 서버 컴포넌트의 결과를 가져와서 사용할 수 있다. | ||
- 렌더링 생명주기를 사용할 수 있다. | ||
서버 컴포넌트를 직접 구현하기는 쉽지 않다. | ||
서버 사이드 렌더링도 어려웠는데, 얘는 더 어렵겠쥐ㅋ | ||
리액트 팀에서 제공하는 공식 예제에서도 서버 컴포넌트를 위해 react-server-dom-webpack를 사용한다. | ||
|
||
### 11.2.3 서버 사이드 렌더링과 서버 컴포넌트의 차이 | ||
|
||
### 11.2.4 서버 컴포넌트는 어떻게 작동하는가? | ||
|
||
[링크](https://nextjs.org/docs/app/building-your-application/rendering/server-components#how-are-server-components-rendered)를 참고하자! | ||
|
||
1. 렌더링은 개별 경로 or 서스펜스 경계를 기준으로 청크로 분할 | ||
2. [서버 react] RSC Payload 형식으로 서버 컴포넌트를 렌더링 | ||
3. [서버 next] RSC Payload 및 클라이언트 컴포넌트를 서버에서 HTML로 렌더링 | ||
4. [클라이언트] 클라이언트 컴포넌트를 렌더링 | ||
|
||
이거 다시 한번 정리하것습니다 이해가 잘 안 되네용 | ||
|
||
## 11.3 Next.js에서의 리액트 서버 컴포넌트 | ||
|
||
### 11.3.1 새로운 fetch 도입과 getServerSideProps, getStaticProps, getInitialProps의 삭제 | ||
|
||
과거의 잔재, 영광의 유물이었던 getServerSideProps, getStaticProps, getInitialProps가 삭제되었다. | ||
이제는 대`**fetch**`를 사용하여 데이터를 가져온다. | ||
> fetch 사용하면 되니까 react-query나 다른 것들을 사용하지 않아도 되어서 좋긴 하네요! | ||
|
||
### 11.3.2 정적 렌더링과 동적 렌더링 | ||
|
||
기존의 staticProps처럼 빌드 타임에 렌더링을 미리 해두어 결과물을 CDN에 캐싱하여 더욱 빠른 속도로 제공할 수 있다! | ||
13부턴 기본적으로 정적인 라우팅의 경우 기본적으로 빌드 타임에 렌더링을 미리 하는 것으로 변경되었다! | ||
차이점은 따로 getStaticProps를 사용하지 않아도 된다는 것이다!!!!!!!!! | ||
fetch에 상당히 많은 옵션이 추가되어서 요건 추후 꼭 찾아봐야겠다. | ||
|
||
### 캐시와 mutating, 그리고 revalidating | ||
> 이브, 프시케 그리고 푸른 수염의 아내 ㄷㄷ | ||
|
||
revalidate 옵션을 통해 캐시를 얼마나 오래 유지할지 설정할 수 있다. | ||
> 책에서 revalidate 할 때 router.refresh vs revalidatePath ?,, 뭐가 더 좋아요?! | ||
> 클라에서 할 땐 router.refresh 만 사용이 가능한 건가요? | ||
|
||
### 11.3.4 스트리밍을 활용한 점진적인 페이지 불러오기 | ||
|
||
기존 서버 사이드 렌더링의 경우 전체 페이지를 렌더링한 후에 클라이언트로 전송했다. | ||
이 방식은 렌더링이 끝날 때까지 사용자는 아무것도 볼 수 없었기에 TTFB가 길어지는 문제가 있었다. | ||
스트리밍을 사용한다면, 서버에서 렌더링이 끝날 때까지 기다리지 않고 렌더링이 끝난 부분을 클라이언트로 전송하여 사용자가 빠르게 페이지를 볼 수 있게 할 수 있다. | ||
이 때 클라이언트에 컴포넌트가 완성되는 대로 렌더링을 한다면 로딩 중임을 알 수 있게끔 해줘야 하는데, 이를 위해 Suspense를 사용한다. | ||
|
||
## 11.4 웹팩의 대항마, 터보팩의 등장 | ||
|
||
> 사용해보신 분?! | ||
> swc, babel, webpack, turbopack, esbuild, parcel, vite 등등 이런 것들이 어떤 관계인지, 어떤 역할을 하는지 넘나 헷갈리네요 | ||
Comment on lines
+141
to
+144
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 스크립트로 dev:turbo 이렇게 뚫어두기만 하고 ... 사용해보진 않았네요 😢 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. swc: babel 대체제 (Es 2015 와 같이 이전 브라우저에서 구동 가능한 javascript로 변환해주는 트랜스파일러) |
||
|
||
## 11.5 서버 액션 | ||
|
||
> 저번에 우연치않게 강동윤님을 만나게 되었는데, 그 분께서 요 기능 정말 괜찮다고 하시더라구요! | ||
서버 액션은 API를 굳이 생성하지 않아도 함수 수준에서 서버에 접근하여 데이터 처리를 할 수 있다. | ||
Comment on lines
+148
to
+149
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 😮 |
||
서버 컴포넌트와의 차이점은 함수 실행 자체만을 서버에서 수행할 수 있다. | ||
> 경험 | ||
> 에러 핸들링 할 때나 함수 실행 결과를 반환할 때 컨벤션이나 인터페이스를 잘 정의해놔야 협업할 때의 혼란을 줄일 수 있을 것 같더라구요! | ||
> 편하긴 편했어요. | ||
|
||
## 11.8 정리 | ||
|
||
다시 한번 읽어야 할 정도로 기존에 알던 지식들과 다른 점들이 많았다. 서버 사이드 렌더링과 서버 컴포넌트는 많이 다르다. | ||
요건 실제로 사용을 해보며 경험하는 것이 더 좋아보여요. 더불어 공식문서 정말 자세하게 나와있으니 꼭 보십시오,,! | ||
더불어 app 디렉터리의 등장으로 레이아웃을 적용하는 것이 훨씬 편해졌고, 다양한 기능들이 추가되며 기존 react-hook-form, react-query, axios 등등의 라이브러리들을 사용하지 않아도 되어서 좋아보였다. | ||
> 서버 컴포넌트 사용하며 폼 검증은 보통 어떻게 하시나요? 저번에 react-hook-form을 사용해 보았는데, 조금 까다로워서 그냥 서버측에서 zod로 검증을 하는 방식을 사용했었어요. | ||
> 이 때 서버 액션의 적절한 인터페이스 선언이 중요할 것 같다고 생각이 들었고요! | ||
|
||
[앱 라우터를 사용할 때 주로 하는 10가지 실수들](https://youtu.be/RBM03RihZVs?si=p5kjrWtGZCO29643) | ||
[앱 라우터 캐싱 설명](https://youtu.be/VBlSe8tvg4U?si=B19SnSn_eM7I4KYd) | ||
Comment on lines
+167
to
+169
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 👍 😮 🚀 🎸 👩🎤 👨🎤 |
||
|
||
요거 두 영상 추천드리옵니다! 갓셀 VP면 무적권. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 👍 👍