NEXT.js 파고들기

Sunny·2023년 5월 19일
0

Front End

목록 보기
1/2

Next.js 는 React로 SSR(Server Side Rendering) 을 보다 쉽게 구현하기 위한 프레임워크 이다. 따라서 그 전에 SSR과 그와 관련한 CSR, SSG에 대해서 먼저 알아보자.

1. SSR? CSR? SSG?

1.0 MPA vs SPA

MPA

다수의 페이지로 구성되어 요청마다 정해진 페이지를 반환

SPA

단일 페이지로 구성되어 해당 페이지 자체에서 요청에 따라 화면을 재구성

1.1 SSR (Server-Side-Rendering)

MPA가 SSR방식이다. MPA 형태에서는 이미 하드코딩 된 정적 페이지들을 개별적으로 서버가 가지고 있다. 따라서 요청마다 서버는 해당 요청에 상응하는 정적페이지를 하나 찾아서 반환을 해주게 된다. 이는 결국 렌더링이 서버 사이드에서 완료되어 최종 문서를 반환하고 있는 형태이다.

  • SSR 방식이 이루어지는 순서
    1. 유저가 웹사이트 요청을 보냄
    2. 서버는 즉시 렌더링 가능한 html 파일을 만듬
    3. 클라이언트에 전달되는 순간, 이미 렌더링 준비가 되어있어서 html은 즉시 렌더링 됨. 그러나 사이트 조작은 불가능 (JS가 읽히기 전이라)
    4. 클라가 JS를 다운받는다
    5. 다운받는 사이에 유저는 컨텐츠는 볼 수 있지만 사이트를 조작 할 수는 없다. 이때의 사용자 조작을 기억하고 있음!
    6. 브라우저가 JS 프레임워크를 실행한다.
    7. JS까지 성공적으로 컴파일 되었기 때문에, 기억하고있던 사용자 조작이 실행되고, 웹페이지는 상호작용 가능해진다.

SSR은 HTML파일을 렌더링을 마친 상태로 응답하기 때문에 로딩시간이 상대적으로 짧다.

장점

  1. 첫 페이지 로딩 시간이 CSR 방식과 비교해 매우 짧다. (별도의 JS 파일 등을 다운받아 적용하기까지는 시간이 좀 더 소요되어 사용자의 인터랙션에 정상적인 반응을 보일때까지 기다리는 시간이 어느정도 발생할 수 있다)
  2. 이미 렌더링 된 HTML 문서가 전달되므로 SEO이 CSR방식에 비해 적용하기 더 우수하다.
    • SEO? 👉 **검색 엔진 최적화** 웹 사이트가 검색 결과에 더 잘 보이도록 최적화 하는 과정이다. 검색 랭크 개선이라고도 한다. 웹 페이지 검색엔진이 자료를 수집하고 순위를 매기는 방식에 맞게 웹 페이지를 구성하여 검색결과의 상위에 나타나게 한다.
  3. 사용자 정보를 서버측 세션으로 관리하기 용이하므로 CSR 방식에 비해 보안이 우수하다.

단점

  1. 페이지 전환 간에 깜빡임 현상이 존재한다. 페이지를 이동할 때마다, 서버에서 렌더링 해주는 새로운 파일을 받기 때문이다.
  2. 페이지를 이동할 때마다 서버에서 렌더링 하여 파일을 주기 때문에 느리다.
  3. 새로운 파일을 받아서 다시 필요한 파일을 로드하는 것이기 때문에, 클라이언트단에서 메모리에 데이터를 유지할 수가 없다.
  4. 서버가 렌더링 한다는 것은 서버가 담당하는 일이 더 많아지는 것이기 때문에 과부하에 걸릴 위험이 존재한다.

1.2 CSR (Client-Side-Rendering)

SPA가 CSR방식이다. SPA 형태에서는 최초 요청 시에 서버로부터 HTML 문서를 전달받는다. 해당 문서는 비어있는 HTML 문서나 다름이 없다. 최초로 받아온 HTML문서를 가지고 렌더링에 필요한 기타 다른 파일(JS같은거)을 로드하여 클라이언트단에서 렌더링을 실시해 화면을 구성한다.

  • SPA가 더 어리대 SPA개념이 MPA보다 이후에 탄생했다. 모바일 시대가 오면서 성능이 PC보다 떨어지는 모바일 디바이스에 최적화를 보장하기 위해서와 SPA 형태의 웹 사이트가 조금 더 유저 친화적인 사용자 경험을 선사해준다는 이유 등이 있다.

하나의 페이지에 여러 페이지를 보여 주는것은 자바스크립트를 이용해서 페이지의 일부분이나 전체를 바꾸는것이다. jsx와 js같은 파일들은 Webpack과 같은 번들링 도구를 거쳐 하나의 거대한 js파일로 번들링한다. SPA에서는 이처럼 번들링 된 js를 전달받아 Single Page Application을 구축하게 된다.

즉 CSR 방식 에서는 번들링이 완료된 js 파일을 모두 로드하기 전에는 첫 페이지를 로드 할 수가 없다. (처음엔 빈 html파일이 로드 돼있다.)

  • SSR 방식이 이루어지는 순서
    1. 유저가 웹사이트 요청을 보냄
    2. CDN이 HTML 파일과 JS로 접근할 수 있는 링크를 클라이언트로 보낸다.
    3. 클라이언트는 HTML과 JS를 다운받는다. (이때 html이 비어있음)
    4. 다운 완료된 JS가 실행되고 데이터를 위한 api가 호출된다.
    5. 서버가 api로 부터의 요청에 응답한다.
    6. api로부터 받아온 data를 넣어준다.

장점

  1. 초기 로딩 속도를 제외하면 나머지 부분은 매우 빠른 반응 속도를 보여준다. 이미 다운받은 번들링 된 js파일에 렌더링에 필요한 모든 로직이 들어있기 때문이다.
  2. 새로고침이나 화면 깜빡임이 존재하지 않는다.
  3. 서버가 클라이언트 단에서 처리할 일을 신경쓰지 않아도 된다.

단점

  1. 초기 Javascript 파일을 전부 로드한 후, 뷰를 구성해야하기 때문에 어플리케이션이 커질수록 구동시간이 점점 느려진다.
  2. 초기 로딩 속도가 늦어 유저는 로딩이 완료되기 까지 빈 화면을 보고있어야 한다.
  3. Javascript 파일을 전부 로드해야 페이지 정보를 구성할 수 있으므로 SEO에도 취약한 문제가 있다. (검색 엔진이 해당 문서를 볼 때 기입된 내용 없이 빈 html 이라서)

1.3 SSG (Static-Site(Side)-Generation)

Static-Rendering 라고도 한다. 해당 방식은 클라이언트에서 필요한 페이지들을 서버에서 사전에 미리 준비해 뒀다가, 요청을 받으면 이미 완성된 파일을 단순히 반환하여 브라우저에서 뷰를 보여지게 하는 방식이다. SSR과 비슷해 보이지만 다른점은 HTML 파일의 생성 시점이 빌드타임 이라는 것.

SSR은 엄밀히 말하면 SSG에 속한다.(둬허란나 줘헌나 헷갈리네...)

장점

  1. 이미 Pre-rendering된 정적 파일이 있어서 서버에서는 단지 그 파일을 클라이언트로 전달해 줄 뿐이라 정말 빠르다.
  2. SSR과 마찬가지로 이미 생성된 HTML을 받기 때문에 SEO 친화적이다.

단점

  1. 웹사이트의 수많은 페이지들을 전부 정적 파일로 만들어주기에는 현실적으로 무리가 있다.
  2. 모든 URL에 대해 개별 HTML 파일을 생성하기 때문에 URL을 미리 예측할 수 없으면 적용이 어렵다.

2. NEXT.js

2.1 NEXT.js 란?

SPA는 기본적으로 CSR 방식을 사용하여 동작한다. 하지만, CSR 방식이 가진 단점을 극복하려고 SSR개념을 !부분 적용!하면 좋은데, 그것을 쉽게 하기 위해 NEXT를 사용하는 것이다.

즉, NEXT는 React와 같은 SPA(CSR)에 SSR을 쉽게 적용하기 위한 프레임워크 및 라이브러리이다.

외에도 Code Splitting, Image Optimazation, Pre-fetching과 같은 기능도 함께 제공하고있다.

첫 페이지 로딩을 SSR방식으로 적용해 렌더링 하고, 나머지는 CSR을 쓰는 방식으로 하면 각자의 장점을 사용 할 수 있어서 좋다. SSR로 인해 초기 렌더링 속도가 빠르고 SEO에 최적화 되어있으며, 이후 CSR을 이용하여 페이지간 이동이 빠르고 새로고침 현상이 없게 되기 때문이다.

2.2 NEXT에서의 CSR, SSR, SSG

NEXT는 브라우저에 렌더링 할 때 기본적으로 pre-redering을 한다고 소개한다.(공식문서)

React에서는 (어떠한 라이브러리나 프레임워크를 사용하지않은) CSR 방식이 사용된다. 하지만 React와 NEXT.를 함께 사용하게 되면 pre-rendering을 하여 빌드 타임때 해당하는 페이지 별로 html문서를 미리 생성해 가지고 있다가 서버로 요청이 들어올 때 알맞은 페이지를 반환해준다.

NEXT에서 Pre-rendering을 하기 위해 두가지 방식을 사용하는데 바로바로 SSG와 SSR이다!

  1. SSG (추천, default) : HTML을 빌드 타임에 각 페이지 별로 생성하고 해당 페이지로 요청이 올 경우 이미 생성된 html 문서를 반환
  2. SSR : 요청이 올 때마다 해당하는 html 문서를 그때 그때 생성하여 반환

두 방식은 모두 pre-rendering을 하지만 언제, 어떻게 제공하는지의 차이이다.

NEXT에서의 SSG방식

  1. pages 폴더에서 작성한 각 페이지들에 대한 각각의 html 문서를 생성해서 static 문서로 가지고 있는다. (pages 폴더가 뭔지는 밑에서..)
  2. 유저의 요청이 발생하면, 요청에 따라 서버에서 계속 재생성 하는 것이 아니라 이미 생성이 완료된 페이지를 반환한다.
  3. 따라서 응답속도가 매우 빠르다.

NEXT에서는 다음과 같은 경우에 SSG 사용을 권장한다.

  • 성능에 집중 할때 (빠른 응답 가능)
  • 마케팅 페이지 / 블로그 게시물 / 제품의 목록 등과 같이 정적 생성하여 각 요청에 동일한 문서를 반환할 수 있는 경우.

NEXT에서의 SSR방식

유저의 요청 때마다 그에 상응하는 html 문서를 생성하여 반환한다.

NEXT에서는 다음과 같은 경우에 SSR 사용을 권장한다.

  • 항상 최신 상태를 유지해야 하는 경우 (요청 할때마다 응답하는 값들이 변함)
  • 제품의 상세 페이지 / 분석 차트 등 요청마다 다른 내용 또는 형식의 html 문서가 반환되는 경우

그렇다면 NEXT를 사용하면 CSR을 사용하지 않을까? → 아님!

NEXT에서의 CSR방식

위에서 말한 SSG 방식이 CSR을 대체하는 개념이다.

기본적으로 SPA는 CSR 방식이 기본이다. (NEXT에서도 링크 걸면 새로고침 없이 이동함 → NEXT도 react를 사용하니까 SPA!)

NEXT를 사용하면 CSR+(SSG or SSR) 을 사용할 수 있다.

Next 공식문서에서는 만약 데이터의 변동이 매우 빈번하게 일어난다면 굳이 pre-rendering을 취하지 말고 기존 react에서 처럼 data-fetching을 통해 클라이언트 사이드에서 렌더링 할 것을 권고한다.

예시
공식 문서에서는 예를 들어 유저 대시보드 같은 웹을 CSR 방식으로 하면 좋다고 한다.
1. 개인적인 영역으로 SEO를 적용해야할 필요가 거의 없어서.
2. 유저의 수정을 통해 즉각적으로 화면이 변동하기 때문에

어떨때 뭘 사용 해야 할까?

  1. 굳이 SEO 적용 또는 데이터 pre-rendering이 필요 없다면 CSR 방식
  2. 정적 문서로 충분한 화면이면서 빠른 HTML 문서 반환이 필요하다면 SSG 방식
  3. 매 요청마다 달라지는 화면이면서 서버 사이드로 이를 렌더링 하고자 한다면 SSR 방식

3. NEXT 환경 세팅

3.1 설치

Automatic Setup - CNA

yarn create next-app

//or

npx create-next-app

With TS

npx create-next-app --typescript

//or

yarn create next-app --typescript
  1. next, react, react-dom 설치
npm install next react react-dom

//or

yarn add next react react-dom
  1. package.json 열어서 scripts 작성
"scripts": {
  "dev": "next dev", //development mode에서 next 시작
  "build": "next build", //어플리케이션 build
  "start": "next start", //next production server 시작
  "lint": "next lint" // eslint 에서의 Next setting
}
  1. pages와 public 폴더 생성
  2. pages폴더에 index.js 파일 생성

위와 같은 설치 후에는 yarn dev 명령어를 통해서 (기존 react에서 yarn start와 같음) 어플리케이션을 locallhost:3000 에서 실행 시킬 수 있다.


4. NEXT.js 구조 with CNA

  • 폴더구조

4.1 Pages

라우팅

NEXT에서 page는 pages폴더 내에서 .js .jsx .ts .tsx 파일에서 내보내지는 리액트 컴포넌트 이다.

각 page는 route와 연관되어있는데 pages 폴더 내에 파일 이름을 기반으로 쉬운 라우팅을 할 수 있다! 이는 next가 제공하는 automatic routing 기능 이다.

기본적으로 메인페이지를 이루는 라우팅인 / 는 pages 내부의 index.tsx or index.jsx 파일이 내보내는 컴포넌트가 된다.

만약에 **pages 폴더 내에 test.tsx 라는 파일을 만들거나, test폴더를 만들어 내부에 index.tsx 파일을 생성한다면** 해당 웹 페이지의 라우팅 주소는

페이지 주소/test

만약 pages 폴더 내에 auth 폴더를 만들고 내부에 login.tsx , join.tsx 파일을 만들면 각 페이지 라우팅 주소는

페이지 주소/auth/login
페이지 주소/auth/join

이와 같이 단순히 폴더를 생성하고 파일을 만들어 주는 것 만으로도 라우팅 작업을 따로 하지 않아도 된다!

동적 라우팅

위와 마찬가지로 pages 폴더 내에 폴더와 파일을 만들어 주면 된다. 단, 파일 이름을 [id].tsx 와 같이 만들어 줄것.

그러면 라우팅 주소는

/test/[id]

와 같이 될 것이고 실제로 /test/1, /test/2 와 같이 동적 라우팅을 할 수 있다.

  • 소담 pages 폴더 구조
    📂 pages
    │   ├── _app.tsx
    │   ├── _document.tsx
    │   ├── 📂 auth
    │   │   ├── join.tsx
    │   │   └── login.tsx
    │   ├── index.tsx
    │   ├── 📂 map
    │   │   ├── [areaId].tsx
    │   │   ├── index.tsx
    │   │   └── list.tsx
    │   ├── mypage.tsx
    │   ├── 📂 review
    │   │   ├── 📂 detail
    │   │   │   └── [reviewId].tsx
    │   │   ├── 📂 my
    │   │   │   ├── emptyScrap.tsx
    │   │   │   ├── emptyWrite.tsx
    │   │   │   ├── scrap.tsx
    │   │   │   └── write.tsx
    │   │   └── write.tsx
    │   └── 📂 shop
    │       ├── collect.tsx
    │       ├── collectEmpty.tsx
    │       ├── 📂 detail
    │       │   └── [id].tsx
    │       └── 📂 theme
    │           └── [type].tsx

index.tsx

기본 메인이 되는 홈페이지

_app.tsx

가장 먼저 실행되며, 레이아웃을 잡거나 각 페이지 별로 공통 로직을 처리할 때 사용할 수 있다.(global css 사용, Header/Footer/Navbar 등 삽입)

_document.tsx

_app.tsx 이후에 실행된다. 공통적으로 사용하는 메타 태그 등을 삽입할 수 있는 파일이다.

해당 파일에서는 이벤트 핸들러를 사용할 수 없다.

4.2 Styles & Public

Styles

정적 자원 중 CSS 파일을 별도로 보관하는 폴더.

global css를 보관하게 되며 이러한 global css는 오직 _app.tsx 파일 에서만! import 하여 사용하면 된다. 그러면 모든 컴포넌트 파일에서 사용 가능하다.

Public

정적 자원을 주로 보관하는 root 디렉토리 이다.

주로 assets 파일(images, fonts 등등)들을 넣어둠.


5. Pre-Rendering (feat. Data-Fetching)

NEX는 Pre-Rendering을 통해서 모든 페이지를 미리 렌더링 하고 성능 향상과 SEO 최적화를 진행한다.

이 과정을 어떻게 구현하는지 알아보쟈!

5.1 SSG 방식

getStaticProps

getStaticProps를 사용하게 되면, NEXT는 getStaticProps로 부터 반환된 props를 이용하여 getStaticProps가 사용된 페이지를 pre-render 한다.

getStaticProps는 빌드 시에 딱 한 번만 호출 되고 바로 static file로 빌드 되어 정적 파일이 된다. 따라서 이후 수정이 불가능하다.

딱 한번 호출 후에 매번 data fetch를 하지 않으니 아주아주 빠르다.

  • 언제 사용해야 할까?
    • 페이지를 렌더 하기 위해 요청되는 데이터가 유저가 요청할 때가 아니라 빌드 타임에 사용 할 때. (SSG)
    • headless CMS에서 데이터가 올 때
    • 유저와 상관 없이 public cache 할 수 있는 데이터
    • 사전 렌더링 되어야 하고 (SEO 최적화) 매우 빠르게 동작하여야 할때

getStaticProps가 기본적으로 받는 context 매개 변수

  • params : 동적 라우트 페이지라면, 동적 라우팅의 경로 이름을 가져온다.
  • preview : preview 모드 여부
  • previewData : 설정한 미리보기 데이터를 포함한다.
  • locale: 활성 로케일을 포함한다.
  • locales: 지원되는 모든 로케일을 포함한다.
  • defaultLocale: 구성된 기본 로케일을 포함한다.

반환값

  • props : 키-값 쌍. 이 값을 반환하여 페이지에 데이터를 붙여준다.

사용 예시 코드 (공식 문서)

function Blog({ posts }) {
  return (
    <ul>
      {posts.map((post) => (
        <li>{post.title}</li>))}
    </ul>)
}

export async function getStaticProps() {
  
  const res = await fetch('https://.../posts')
  const posts = await res.json()

  return {
    props: {
      posts,
    },
  }
}

export default Blog

getStaticPaths

동적 라우팅 페이지에서 getStaticProps로 ****pre-render하여 static 페이지를 생성할 때 사용한다. (즉, 동적 라우트 페이지 인데 getStaticProps를 사용하고 싶을 때)

동적 라우팅을 사용할 때, 어떤 페이지를 미리 static으로 빌드할 지 정하여 경로를 제공해 주는 것이다.

  • 언제 사용해야 할까?
    • 동적 라우팅 페이지를 static 페이지로 제공해야 할 때
    • 많은 static 페이지를 생성해야 하지만 빌드 시간이 너무 오래 걸릴때

반환 값

  • paths : 빌드 타임에 pre-rendering할 경로들
  • fallback: paths 이외의 경로들에 대해 추후에 요청이 들어오면 정적 페이지를 만들지 말지. 안 만든다면 404리턴

사용 예시 코드

function Blog({ posts }) {
  return (
    <ul>
      {posts.map((post) => (
        <li>{post.title}</li>))}
    </ul>)
}

export const getStaticPaths = async () => {
  const res = await fetch('https://.../posts')
  const posts = await res.json()

  const paths = posts.map((post) => ({
    params: { id: post.id },
  }))

  // { fallback: false } 는 다른 routes들은 404임을 의미
  // true이면 만들어지지 않은 것도 추후 요청이 들어오면 만들어 줄 거라는 뜻
  return { paths, fallback: false }
}

export async function getStaticProps({params}) {
  
  const res = await fetch(`https://.../posts/${params.id}`)
  const posts = await res.json()

  return {
    props: {
      posts,
    },
  }
}

export default Blog

5.2 SSR 방식

getServerSideProps

getServerSideProps는 빌드와 상관 없이 매 페이지 요청마다 Pre-rendering 하여 데이터를 서버로 부터 가져온다. (매 페이지 요청마다 새로 렌더링 하여 반환하는 것)

매 요청마다 호출 되어 성능은 getStaticProps보다 떨어지지만 (소담 눈감아..) 내용이 언제든 동적으로 수정 가능하고 보여진다.

getServerSideProps는 서버사이드에서만 실행되고, 절대로 브라우저에서 실행되지 않는다. 또한, 요청 시점에 실행되고 그 결과의 값을 props로 넘겨준 뒤 렌더링을 하게된다.

  • 언제 사용해야 할까?
    • 페이지를 렌더링 하기 전에 반드시 fetch 해야할 데이터가 있을 때.

    • 데이터가 새로고침 마다 동적으로 변경될 경우

      렌더링 하기전에 반드시 fetch 해야하는 경우가 아니라면 CSR이나 SSG방식을 사용하는것이 좋다구 합니다. (소담 눈감아 22..)

getServerSideProps가 기본적으로 받는 context 매개 변수

  • params : 동적 라우트 페이지라면, 동적 라우팅의 경로 이름을 가져온다.
  • req : http request obejct
  • res: http response object
  • query: 쿼리스트링
  • preview : preview 모드 여부
  • previewData : 설정한 미리보기 데이터를 포함한다.
  • locales: 지원되는 모든 로케일을 포함한다.
  • defaultLocale: 구성된 기본 로케일을 포함한다.

반환값

  • props : 데이터의 키-값 쌍. 이 값을 반환하여 페이지에 데이터를 붙여준다.

사용 예시 코드

const Detail = ({ item }) => {
  return (
    <div className="Detail">
      <h1>{item.title}</h1>
      <p>{item.body}</p>
      <p>{item.id}번째 게시글</p>
    </div>
  );
};

export default Detail;

export const getServerSideProps = async (context) => {
  const id = context.params.id;
  const res = await axios.get(
    `https://.../posts/${id}`);
  const data = res.data;

  return {
    props: {
      item: data,
    },
  };
};

getInitialProps

현재는 getInitialProps 대신에 위의 세가지 방식을 사용하는것을 권장한다.

NEXT는 기본적으로 자동 정적 최적화를 하는데 자동 정적 최적화란, getInitialProps가 없으면, 페이지를 정적 HTML 으로 사전렌더링 해서 정적 최적화를하는 것이다.

그러나 전역적으로 getInitialProps를 사용하게 되면, 이러한 최적화 과정이 일어나지 않는다. 때문에 현재는 분리해서 위의 세가지 방식을 사용하는 것이다.

위의 세가지 방식은 전역적인 데이터 패치 기능을 지원하지 않는다. 따라서 전역적으로 SSR 패칭을 해야만 하는 경우라면 getInitialProps를 써야만 한다! 페이지 별로 데이터 패칭은 위의 세가지 방식을 사용한다

getServerSideProps가 기본적으로 받는 context 매개 변수

  • ctx 객체 : Component로 보내는 객체
    • pathname- 현재 pathname /user?type=normal page 접속 시에는 /user
    • query- 현재 query를 object형태로 출력 /user?type=normal page 접속 시에는 {type: 'normal'}
    • asPath - 전체 path /user?type=normal page 접속 시에는 /user?type=normal
    • req - HTTP request object
    • res - HTTP response object
  • Component : 해당 컴포넌트

사용 예시 코드

_app.tsx 파일 내부

function MyApp({ Component, pageProps }) {
  return (
    <>
      <Head>
        <title>Next!</title>
      </Head>
      <AppLayout>
        <Component {...pageProps} />
      </AppLayout>
    </>
  );
}

MyApp.getInitialProps = async (context) => {
  const { ctx, Component } = context;
  let pageProps = {};

  if (Component.getInitialProps) {
    // Component의 context로 ctx를 넣어주자
    pageProps = await Component.getInitialProps(ctx);
  }

  // return한 값은 해당 컴포넌트의 props로 들어가게 됩니다.
  return { pageProps };
};

5.3 CSR방식 (Pre-Rendering X)

NEXT에서도 CSR방식을 사용하여 데이터 패칭을 할 수 있다. 우리가 일반적으로 리액트에서 맨날 하던 그것이다.

useEffect 사용

const About = () => {
  const [list, setList] = useState([]);

  useEffect(() => {
    const getList = async () => {
      const res = await axios.get(`https://jsonplaceholder.typicode.com/posts`);
      const data = res.data;
      setList(data);
    };
    getList();
  }, []);

  return (
    <div className="About">
      <h1>여기는 About 페이지요!</h1>
      {list.length &&
        list.slice(0, 10).map((item) => <li key={item.id}>{item.title}</li>)}
    </div>
  );
};

6. NEXT 의 여러 태그들 (은 소담에서 쓴거)

6.1 next/router

router 내부에 라우트 정보 객체를 가지고 있으며, 다양한 메소드(etc: .push / .back / .replace)를 이용할 수 있다.

import { useRouter } from "next/router";

export default function App() {
  const router = useRouter();
  return (
    <div>
      <h2>Link to 'tomato' Page</h2>
      <button onClick={() => router.push("/tomato")}>토마토로 가기</button>
    </div>
  );
}

그러나 seo에 영향을 미치는 크롤러는 router.push() 가 다른 페이지로 이동하는 링크라고 인식하지 않는다.

따라서, Link 컴포넌트를 활용하는게 좋다.

NEXT에 내장 된 클라이언트 사이드 라우팅 기능

import Link from 'next/link'

function Home() {
  return (
    <ul>
      <li>
        <Link href="/">
          <a>Home</a>
        </Link>
      </li>
      <li>
        <Link href="/about">
          <a>About Us</a>
        </Link>
      </li>
      <li>
        <Link href="/blog/hello-world">
          <a>Blog Post</a>
        </Link>
      </li>
    </ul>
  )
}

export default Home

동적 라우팅

import Link from 'next/link'

function Posts({ posts }) {
  return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>
          <Link href={`/blog/${encodeURIComponent(post.slug)}`}>
            <a>{post.title}</a>
          </Link>
        </li>
      ))}
    </ul>
  )
}

export default Posts

custom된 a태그를 래핑하는 link 태그 or 함수로 반환된 Component를 래핑하는 link 태그 → passHref를 꼭 써줘야됨 (소담에서는 Button 태그를 래핑할 때랑 여러 태그를 한꺼번에 래핑하는 경우에도 사용해줬는데.. 정확하게 모르겠다 아마 Lint에 걸렸던듯)

import Link from 'next/link'
import styled from 'styled-components'

const RedLink = styled.a`
  color: red;
`

function NavLink({ href, name }) {
  return (
    <Link href={href} passHref>
      <RedLink>{name}</RedLink>
    </Link>
  )
}

export default NavLink

6.3 next/image

이미지를 자동으로 최적화 해줌

built-in 성능을 최적화 하기 위해 를 확장한 것.

import Image from 'next/image';

function ShopCard(props: ShopCardProps) {
  const { cardData } = props;
  const { image, shopName, category, shopId } = cardData;

  const joinCategory = () => {
    if (typeof category === 'string') return category;
    return category.join(', ');
  };

  return (
    <Link href={`/shop/detail/${shopId}`} passHref>
      <StyledRoot>
        <Image
          src={image[0]}
          width={282}
          height={208}
          alt="thumbnail"
          placeholder="blur"
          blurDataURL={image[0]}
        />
        <StyledTitle>
          <h3>{shopName}</h3>
          <p>{joinCategory()}</p>
        </StyledTitle>
      </StyledRoot>
    </Link>
  );
}

6.4 next/head

페이지에 title, meta 태그를 넣어주기 위한 컴포넌트 → seo 사용하기 위해서 meta 태그가 필요함

import Head from 'next/head'

function IndexPage() {
  return (
    <div>
      <Head>
        <title>My page title</title>
        <meta name="viewport" content="initial-scale=1.0, width=device-width" />
      </Head>
      <p>Hello world!</p>
    </div>
  )
}

export default IndexPage

참고자료

Getting Started | Next.js
CSR, SSR, SSG 조화를 이루다.
[FE] CSR(Client-Side-Rendering) vs SSR(Server-Side-Rendering) (feat. React를 중점으로)
SSR과 CSR의 차이
next.js 기본 개념 알아보기
Next.js 프로젝트 디렉토리 구조
Next.js 100% 활용하기 (feat. getInitialProps, getStaticPath, getStaticProps, getServerSideProps, storybook)

profile
FrontEnd Developer

0개의 댓글