이 글은 Next.js에서 SWR을 이용해 데이터를 가져오는 방법에 대해 설명합니다.
다음 지식들을 안다면 문제없이 읽을 수 있습니다.
- React 기초 문법
- Next.js 기초 문법
- Typescript
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
은 vercel
에서 제작한, 데이터를 가져오기 위한 모듈입니다. SWR
을 Next.js
에서 활용하는 방법을 알아 보겠습니다. 자세한 내용은 SWR 공식 페이지를 참고해 주시기 바랍니다.
SWR의 이론적 내용이나 동작 등에 관해서는 추후에 다루어 보고, 여기서는 SWR을 어떻게 사용하는 지에 대해 설명하려 합니다.
npm i swr
혹은 yarn add swr
을 이용해 설치하면 됩니다.
SWR
은 useSWR
이란 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
에 오류가 기록되고요.
/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
를 이용해 url
에 get
요청을 보내 데이터를 받아옵니다. fetcher
함수와 useSWR
을 이용하면 위 코드와 같이 data
를 받아올 수 있습니다.
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>
위에서 사용한 fetcher
함수는 어디에서 SWR
을 사용하든 동일하게 사용될 것이라 생각되는데, 이 때 마다 동일한 fetcher
함수를 선언하는 것은 굉장히 귀찮은 일입니다. 이 경우 SWR Config
를 이용해 전역적인 설정을 해 줄 수 있습니다. (참고)
<SWRConfig value={options}>
<Component/>
</SWRConfig>
위와 같이 표현하고자 하는 Component
를 SWRConfig
로 감싸고 value
값에 원하는 값을 넣어주면 해당 Component
안에서 전역적인 설정을 다룰 수 있게 됩니다.
만약 모든 Next.js
페이지에서 fetcher
를 고정시키고 싶다면 어떻게 하면 될까요? _app.tsx
파일의 Component
를 SWRConfig
로 감싸주면 됩니다. 다음과 같이 말이죠
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
라는 캐시 무효 전략을 이용해 지속적이고 자동으로 최신화된 데이터를 가져오는 멋진 도구입니다. 자세한 내용은 추후 추가해보겠습니다.
코드 원본은 여기를 참고해 주시면 됩니다.