Next.js에서 SWR을 사용해 보자 - 1 (Fetch)

이준혁·2022년 5월 18일
5

next-tutorials

목록 보기
5/7
post-thumbnail

이 글은 Next.js에서 SWR을 이용해 데이터를 가져오는 방법에 대해 설명합니다.
다음 지식들을 안다면 문제없이 읽을 수 있습니다.

  • React 기초 문법
  • Next.js 기초 문법
  • Typescript

w/o SWR

Next.js에서 사용자가 페이지에 입장하자마자 정보를 보여주려면 어떻게 해야할까요? 페이지가 처음 렌더링될 때 GET 요청을 api에 보내 DB에서 정보를 가져와서 보여 주면 될 것입니다.

const [shopList, setShopList] = useState<string[]>([]);

useEffect(() => {
  axios.get("/api/shops").then((res) => setShopList(res.data.shops));
}, []);

보시다시피 useEffect내에서 api 요청을 보내고 데이터를 가져오는 과정을 진행하는 것을 알 수 있습니다. 하지만 이 과정을 조금 더 편하고 자동으로 만들어주는 hook이 있다면 좋지 않을까요? 이런 이유로 SWR이라는 좋은 모듈이 등장했습니다.

SWR

SWRvercel에서 제작한, 데이터를 가져오기 위한 모듈입니다. SWRNext.js에서 활용하는 방법을 알아 보겠습니다. 자세한 내용은 SWR 공식 페이지를 참고해 주시기 바랍니다.

SWR의 이론적 내용이나 동작 등에 관해서는 추후에 다루어 보고, 여기서는 SWR을 어떻게 사용하는 지에 대해 설명하려 합니다.

설치

npm i swr 혹은 yarn add swr을 이용해 설치하면 됩니다.

useSWR

SWRuseSWR이란 hook을 제공합니다. 다음과 같이 사용됩니다.

import useSWR from 'swr'

function Profile() {
  const { data, error } = useSWR(key, fetcher);
  
  // ...
}

hook에서 인자로 받는 값과 반환하는 값들은 다음과 같습니다.

1. key: SWR의 키, 주로 요청을 보낼 URL이 해당됨
2. fetcher: key값(URL)을 이용해 데이터를 가져오는 함수.
3. data: 요청에 오류가 없는 경우 가져온 데이터
4. error: 요청에 오류가 있는 경우 해당 오류

보통 key값에는 요청을 보낼 URL이 해당됩니다. 반면 fetcher 함수에서는 fetch 혹은 axios를 이용해 데이터를 가져옵니다.

fetcher의 반환값이 오류가 없는 경우에는 data에 들어갑니다. 오류가 있을 때는 error에 오류가 기록되고요.

Example

/api/shops라는 api에서 데이터를 가져오는 SWR hook을 만들어 봅시다.

const fetcher = (url: string) => axios.get(url).then((res) => res.data);
const { data, error } = useSWR("/api/shops", fetcher);

fetcher 함수는 위에 언급한대로 axios를 이용해 urlget 요청을 보내 데이터를 받아옵니다. fetcher 함수와 useSWR을 이용하면 위 코드와 같이 data를 받아올 수 있습니다.

Typescript

Typescript를 사용하고 있다면 다음과 같이 SWR에서 반환하는 데이터의 타입을 지정해 줄 수 있습니다.

interface ShopsReturn {
  ok: boolean;
  shops: string[];
}

export default function Test() {
  const fetcher = (url: string) => axios.get(url).then((res) => res.data);
  const { data, error } = useSWR<ShopsReturn>("/api/shops", fetcher);
  
  return <h1>{data.ok}</h1>

SWRConfig

위에서 사용한 fetcher 함수는 어디에서 SWR을 사용하든 동일하게 사용될 것이라 생각되는데, 이 때 마다 동일한 fetcher 함수를 선언하는 것은 굉장히 귀찮은 일입니다. 이 경우 SWR Config를 이용해 전역적인 설정을 해 줄 수 있습니다. (참고)

<SWRConfig value={options}>
  <Component/>
</SWRConfig>

위와 같이 표현하고자 하는 ComponentSWRConfig로 감싸고 value 값에 원하는 값을 넣어주면 해당 Component안에서 전역적인 설정을 다룰 수 있게 됩니다.

만약 모든 Next.js 페이지에서 fetcher를 고정시키고 싶다면 어떻게 하면 될까요? _app.tsx 파일의 ComponentSWRConfig로 감싸주면 됩니다. 다음과 같이 말이죠

import type { AppProps } from "next/app";
import { SWRConfig } from "swr";
import axios from "axios";

function MyApp({ Component, pageProps }: AppProps) {
  return (
    <SWRConfig
      value={{
        fetcher: (url: string) => axios.get(url).then((res) => res.data),
      }}
    >
      <Component {...pageProps} />
    </SWRConfig>
  );
}

export default MyApp;

이렇게 설정해 주면 useSWR을 사용할 때 fetcher 함수를 넣어주지 않아도 됩니다!

// Before
const { data, error } = useSWR<ShopsReturn>("/api/shops", fetcher);

// After
const { data, error } = useSWR<ShopsReturn>("/api/shops");

마치며

이 포스트에서는 SWR을 이용해 데이터를 가져오는 방법에 대해 간단히 알아봤습니다. 하지만 실제로는 stale-while-revalidate 라는 캐시 무효 전략을 이용해 지속적이고 자동으로 최신화된 데이터를 가져오는 멋진 도구입니다. 자세한 내용은 추후 추가해보겠습니다.

코드 원본은 여기를 참고해 주시면 됩니다.

참고자료

  1. SWR 공식 페이지
  2. SWR Global Configuration
  3. Next JS 강의
profile
만들고 개선하는 것을 좋아하는 개발자

0개의 댓글