Next14: Restart

Lumpen·2024년 8월 28일

Next.js

목록 보기
2/10

React 라이브러리를 사용하는 Framework
react 는 UI 를 구성하고
react-dom 은 렌더링을 담당한다

next 는 실행 시 app 이라는 폴더에서 page.tsx 파일을 찾는다
page.tsx 를 root segment 라고 부른다
패이지의 root 에서 보여줄 페이지가 되는 것
또 layout.tsx 파일을 자동으로 생성한다

따로 typescript 설치를 하지 않았어도
.tsx 로 page 를 작성 후 실행 시 next.js 가 알아서
타입스크립트가 필요함을 감지하고 설치한다

app router

react router 의 작동 방식은 url 을 지정하고
해당 url 에 접속 시 컴포넌트의 렌더링을 요청한다
각각의 url 에 매칭되는 컴포넌트를 일일히 지정해줘야 함

next의 app router 는 파일 시스템을 통해 url 을 표현한다

폴더 명을 통해 url 을 표현한다
폴더 이름을 about-us 로 지정하면 /about-us 로 하나의 페이지가 생성된다
폴더 내부에 page.tsx 를 생성하면 해당 경로의 ui 가 생성된다
page.tsx 가 없는 폴더는 404 error 가 발생, url 경로만 생성된다

404 not found page

next 에서는 404 error 가 발생했을 때의 not found page 를 기본적으로 제공한다
app 내부에 not-found.tsx 파일을 생성하면 not found page 를 커스텀 할 수 있다

components

app 폴더 내의 폴더는 라우팅에 관여하기 때문에
컴포넌트 폴더는 app 외부에 작성한다

react 에서와 같이 링크 이동 시에 a 태그를 사용하지 않는다
next.js 에서는 Link 컴포넌트를 사용

next/navigation 에서 usePathname 훅을 제공하여
현재 경로를 파악할 수 있다

usePathname 은 client component 에서만 작동하기 때문에
'use client' 를 최상단에 작성해주어야 한다

server components

'use client' 를 사용하지 않은 next.js 의 컴포넌트는
모두 서버 컴포넌트가 된다
서버에서만 렌더링 하는 정적 컴포넌트를 말한다
서버 컴포넌트는 서버에서 동작하기 때문에 데이터베이스, 파일 시스템 그리고 인터널 서비스 같은 서버 사이드 데이터 소스에 직접 접근할 수 있다

rendering

react 는 client side rendering 을 사용한다
next.js 를 사용하면 디폴트가 server side rendering
'use client' 를 사용하더라도 첫 렌더링은 서버사이드 렌더링으로 적용된다

hydration

서버 측 렌더링을 통해 전달된 정적 HTML 웹 페이지를
HTML 요소에 이벤트 핸들러를 연결하여 동적 웹 페이지로 변환하는 기술
HTML 을 React application 으로 초기화 하는 작업을 말한다
url 접근 시 정적 html 을 로드 한 후
react 가 client에 로드되면 진행하는 동작이 hydration

hard navigation

웹 페이지 내에서 다른 페이지로 이동할 때
페이지 전체가 새로 로드되는 것을 말한다
a 태그로 페이지를 이동할 때 hard navigation
next.js 를 사용하면 hydration 시 정적 코드가 리액트 코드로 변환되어
페이지 이동 시 새로고침이 발생하지 않는다
navigation 이 client sdie navigation 으로 변환된다
자바스크립트에 의해 네비게이션이 작동하는 것

use client

url 로 접속해 서버에 요청 시
서버에서 컴포넌트를 렌더링 하고 이니셜라이징 하여 초기 html 코드를 건네준다
클라이언트에서는 이를 받아서 html 을 화면에 보여주고
리액트 애플리케이션, 넥스트 애플리케이션을 생성한다
이 hydration 과정은 모든 컴포넌트에서 일어나지 않는다
서버 사이드 렌더링은 모든 컴포넌트에서 발생하지만
클라이언트에서 hydration 되는 컴포넌트는 'use client' 를 사용한 컴포넌트들 뿐이다
'use client' 는 서버사이드 렌더링 되지 않는다는 것이 아니라
hydration 이 되는 컴포넌트를 의미한다

프론트에서 상태를 사용한다면 hydrate 가 필요한 페이지이기 때문에
useState 를 사용할 시 'use client' 를 작성해야 한다

layout.tsx

재사용 하는 요소들에 대해 layout 을 사용할 수 있다

custom layout

layout 은 중첩이 가능하다
custom layout 을 만들 때에는 필요한 라우터의 폴더 내부에 layout.tsx 를 생성하여 만든다
url 에 접속했을 때 상위 url 에 layout 이 적용되어 있다면
url 에도 그걸 적용하여 페이지에 보여준다
url 을 통해 폴더에 접근하고 해당 폴더에 page.tsx 파일이 있는지, layout.tsx 파일이 있는지 확인한다

root layout 을 먼저 적용 후 각 url 별 폴더에 접근하여 차례대로 적용한다

route groups

route 들을 정리하고 그룹화해서 logical 그룹으로 만들 수 있다

여러 layout 을 선택해서 사용할 수 있다
중첩 레이아웃을 사용하지 않게 할 수도 있다

route group 생성 시 폴더 명을 괄호 안에 넣은 폴더를 생성한 후
그룹에 들어갈 폴더 및 파일을 넣어준다
(home) 폴더에 root page.tsx 를 넣어주면 home 그룹을 생성할 수 있다
이름에 괄호를 넣어주면 url 을 생성하지 않은 그룹을 만들 수 있다

meta data

꼭 내보내야 하는 object 로 html meta data 를 구성한다
각 페이지별로 메타 데이터를 구성할 수 있다
메타 데이터는 해당 페이지에서 작성된 것을 우선으로 병합된다
서버 컴포넌트에서만 작성할 수 있다

layout.tsx

import {Metadata} from "next";

export const metadata: Metadata = {
  title: {template: '%s | Next', default: 'Next'},
}

(home)/page.tsx

import {Metadata} from "next";

export const metadata: Metadata = {
  title: 'Home',
}

%s 에 Home 이라는 타이틀이 병합되어
루트 페이지에서 title 은 Home 으로 변경되고
이외의 페이지에서는 default 인 Next 가 된다

metadata 의 변수명은 꼭 metadata 가 되어야 한다

dynamic routes

dynamic routes 는 대괄호로 감싼 이름의 폴더명을 가진 폴더를 만들어주고
다이나믹 라우트를 사용하는 폴더 내부에 page.tsx 를 만들어준다
다이나믹 라우트를 사용하는 페이지의 props 에는 params 가 포함되어 있다
params 에 폴더 이름을 사용하는 라우트명이 있고
searchParams 도 사용할 수 있다

export default function MovieDetail({params: {id}}: {params: {id: string}}) {
  return <div>movie{id}</div>
}

data fetching

next.js 에서 fetch() 를 사용하여 데이터 페칭을 할 경우에만
데이터 캐싱 등을 지원한다

client side

react 에서 client side 에서의 data fetching 은
useState 와 useEffect 를 사용하여
데이터가 있는지 없는지를 체크하여 각각의 화면을 구성하고
렌더링 시 api 를 호출하여 데이터를 불러와 재렌더링을 일으킨다
server 에서 client 와 소통할 api 를 만들어야만 하는 단점도 있음

server side

server components 에서의 데이터 페칭은
useState, useEffect 를 사용하지 않아도 된다
로딩 상태 등을 구현하지 않아도 된다

또한 서버에서 렌더링이 일어나기 때문에 데이터 페칭을 컴포넌트 내부에서 하지 않아도 된다
데이터 페칭 시 컴포넌트 자체에 async 로 사용한다
내부에서 await 을 사용해 가져온 데이터를 받을 수 있도록

이 페칭된 데이터들은 기본적으로 next.js 에서 자동으로 캐싱한다
브라우저에서는 어떤 것도 페칭하지 않는다
때문에 페칭 시에 브라우저에서 걸리는 시간도 없고
어떤 데이터를 페칭하였는지 외부에서 확인할 수 없다

페칭 시의 로딩 상태가 서버로 옮겨졌기 때문에
재렌더링이 일어나지 않는 장점이 있지만
그동안 사용자가 볼 수 있는 화면도 없다
그럴 때는 next.js 의 loading 기능을 사용한다

loading.tsx

next.js 에서 제공하는 loading page 기능을 이용하기 위해서
로딩이 필요한 URL 내부에 loading.tsx 를 만든 후
내부에 로딩 시 보여줄 컴포넌트를 작성하면 된다
그러면 해당 URL 의 컴포넌트에만 로딩 페이지가 생성된다
layout 등 나머지 요소에 영향을 주지 않는다

이러한 기술은 스트리밍 덕분에 가능하다
페이지(백엔드)가 컨텐츠를 스트리밍 한다
http straming 문서를 읽어볼 수도 있다
스트리밍 하는 동안 클라이언트에서는 백엔드가 로딩중이라는 정보만 알 수 있다
그동안 next.js 는 로딩 컴포넌트를 보여주는 것

로딩중이라면 통신은 계속 연결되어 있는 것
next.js 는 로딩중에 웹사이트를 조금씩 보내고 있다

미리 준비된 레이아웃이나 네비게이션을 먼저 보내고
로딩 컴포넌트를 보낸다
그러면서 로딩중인 데이터를 준비한다

이 로딩 컴포넌트 덕분에 조건문으로 구분하지 않아도 되는 좋은 기능
next.js 가 웹 페이지를 html 청크로 나누고 준비된 것들을 하나씩 보내준다

fetching 최적화

Suspense

data fetching 시 Promise.all() 을 이용하여 비동기를 병렬처리 하여
최적화 할 수 있다
하지만 Promise.all() 은 시작만 병렬처리 할 뿐 가장 오래걸리는 함수의
종료 시점까지 기다려야 모두 사용 가능하다

suspense 는 리액트의 기능이다
자식 요소의 코드와 데이터가 렌더링 될 때 까지 기다리면서 구성 요소를
fallback 으로 대체한다

서스펜스를 사용하기 위해
하나의 컴포넌트에서 Promise.all() 로 페칭하고 있던 것을
api 별로 각각 분리해서 컴포넌트를 만든다
각 컴포넌트는 async 이기 떄문에 컴포넌트를 불러오는 쪽에서도 async 를 사용, suspense 를 이용한다
suspense 로 async 컴포넌트들을 각각 감싸준다

이와 같이 하면 각 컴포넌트의 데이터가 페칭되는 순서대로 바로 보여줄 수 있다

suspense 를 사용하면 로딩 페이지가 아니라 각각의 컴포넌트 별 로딩 처리를 할 수 있게 된다

Error Handling

error.tsx 파일을 만들면 에러 발생 시 보여줄 페이지를 띄울 수 있다
에러 컴포넌트도 자신이 속해있는 폴더 내에서만 작동한다
'use client' 로 작성해야 함

profile
떠돌이 생활을 하는. 실업자, 부랑 생활을 하는

0개의 댓글