Next.js 12 -> 13 바뀐 점 [Next]

김민재·2023년 2월 24일
3

Next

목록 보기
1/1
post-thumbnail

회사에서 React 만 쓰다보니, 한동안 Next 를 잘 사용하지 않았다.
새로 13버전이 나왔다고 해서, 바뀐 Next 문법을 정리 해보려고 한다.

1. 라우팅

Next 12버전에서는 pages/ 폴더로 라우팅이 되었는데,
현재 13버전 이후부터는 app/ 폴더로 라우팅이 된다고 한다.

13버전은 과도기라서, pages/, app/ 둘다 지원하는 상태이다.


a. pages/ 기반 라우팅

pages/ 기반 라우팅은 다음과 같이 이루어진다.

pages/test/index.tsx -> /test에 라우팅
pages/test/hello.tsx -> /test/hello에 라우팅
pages/test/[id].tsx -> /test/~ 에 라우팅
pages/test/[...slug].tsx -> /test/~, /test/~/~ .. 등에 라우팅

페이지 간 이동은 다음과 같은 방법으로 한다.

  1. useRouter 이용
import { useRouter } from 'next/router';

router.push('/test')
router.push({ pathname: '/test', query: { id: 1 } })
  1. Link 이용
import Link from 'next/link';

<Link href="/test">페이지 이동</Link>
<Link href={{ pathname: '/test', query: { id: 1 } }}>페이지 이동</Link>

b. app/ 기반 라우팅

app/ 기반 라우팅은 다음과 같이 이루어진다.

app/test/page.tsx -> /test에 라우팅
app/test/hello/page.tsx -> /test/hello에 라우팅
app/test/[id]/page.tsx -> /test/~ 에 라우팅
app/test/[...slug]/page.tsx -> /test/~, /test/~/~ .. 등에 라우팅

이렇게 모든 파일명이 page.tsx여야 한다.
추가적으로 layout.tsx, template.tsx, error.tsx, loading.tsx, not-found.tsx도 쓸 수 있다.
이 파일들의 기능은 아래 그림과 같다.

https://beta.nextjs.org/docs/routing/fundamentals

컴포넌트로 감쌀 필요 없이, 정해진 파일명으로 파일을 만들면 된다는 것이 신기한 것 같다.

그리고, 중첩 라우팅에서 layout.tsx 등도 같이 중첩 된다.

페이지 간 이동 방식은 앞서 pages/ 방식과 동일하다.

2. 서버 사이드 렌더링

React는 기본적으로 클라이언트 사이트 렌더링를 한다.
그래서, 페이지 소스 보기를 누르면 <div id="root"></div> 밖에 안보인다.

Next는 기본적으로 서버 사이드 렌더링을 한다.
그래서 아래와 같이 컴포넌트를 작성한 다음에 페이지 소스를 보면 내용이 나온다.

export default function Home() {
  return <div>Test</div>;
}

// 페이지 소스 보기:
// <div>Test</div>

하지만, fetch, axios 등으로 불러온 데이터는 기본적으로 서버 사이드 렌더링이 안된다.
이를 하려면, Next 12버전에서는 getStaticProps, getStaticPaths, getServerSideProps 등을 이용해야 한다.


a. getStaticProps

먼저 getStaticProps를 살펴 보겠다.

export const getStaticProps: GetStaticProps = async (context) => {
  const res = await fetch('https://jsonplaceholder.typicode.com/todos/1');
  const data = await res.json();

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

getStaticProps 이름을 가진 함수에서,
데이터를 불러온 다음, {props: {data}}를 반환해주면,
이 파일의 export default 된 컴포넌트의 propsdata가 들어온다.

getStaticProps 함수는, 앱 빌드 시 데이터를 미리 가져와서 저장한 다음에
컴포넌트에 뿌려주는 방식으로 작동하기 때문에 속도가 엄청 빠르다.


b. getStaticPaths

다음에는 getStaticPaths를 살펴보겠다.
이는 동적 라우팅인 경우에 getStaticProps와 같이 사용하는 함수이다.

예를 들어서, [id].tsx 라는 파일에 getStaticPaths를 사용한다고 가정하겠다.

import { GetStaticProps, GetStaticPaths } from 'next';

export const getStaticPaths: GetStaticPaths = async () => {
  return {
    paths: [{ params: { id: '1' } }, { params: { id: '2' } }],
    fallback: true,
  };
};

export const getStaticProps: GetStaticProps = async (context) => {
  const res = await fetch(
    `https://jsonplaceholder.typicode.com/todos/${context.params?.id}`
  );
  const data = await res.json();

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

동적 라우팅인 경우는, 가능한 라우팅의 개수가 무한개여서 빌드 시 모든 데이터를 미리 저장하는 것이 불가능하다.
그래서, getStaticPaths를 이용해 무한한 동적 라우팅 중에서, 일부만 선택해서 그것만 미리 빌드하는 것이다.

위 예시는 id 값이 1, 2인 경우만 빌드 시 미리 렌더링하는 경우이다.


c. getServerSideProps

이는 getStaticProps와 같지만, 빌드 시 미리 저장하는 것이 아니라
페이지를 불러오기 직전에 미리 로드하고, 이를 브라우저에 미리 뿌려주는 방식이다.
이를 통해 API 요청 결과의 서버 사이드 렌더링이 가능하다.

export const getServerSideProps: GetServerSideProps = async (context) => {
  const res = await fetch(`https://jsonplaceholder.typicode.com/todos/1`);
  const data = await res.json();

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

d. next 13에서 SSR

next 13에서는 기본적으로 모든 컴포넌트가 서버 사이드 컴포넌트가 된다.
그래서 해당 컴포넌트에서 fetch로 불러오는 데이터는 모두 서버 사이드 렌더링이 된다.

fetch(URL, { cache: 'force-cache' });
fetch(URL, { cache: 'no-store' });

이렇게 fetch에 옵션을 줘서 static 처럼 동작하게 할 수도 있다.

하지만 해당 컴포넌트에서, useState, useEffect 등 훅을 사용하지 못한다.
훅 등은 클라이언트 사이드 컴포넌트에서만 사용해야 한다.

'use client'

export default function Test() {
	return <div>Test</div> 
}

이러한 클라이언트 사이드 컴포넌트에서 훅을 사용하고,
사버 사이드 컴포넌트에서 import 하는 방식으로 이용해야 한다.

server 컴포넌트와, client 컴포넌트를 적절히 사용하는 능력이 중요할 것 같다.

profile
Software Engineer

0개의 댓글