Next.js SWR-1
Next.js SWR-1
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
SWR
은 vercel
에서 제작한, 데이터를 가져오기 위한 모듈입니다. SWR
을 Next.js
에서 활용하는 방법을 알아 보겠습니다. 자세한 내용은 SWR 공식 페이지를 참고해 주시기 바랍니다.
SWR의 이론적 내용이나 동작 등에 관해서는 추후에 다루어 보고, 여기서는 SWR을 어떻게 사용하는 지에 대해 설명하려 합니다.
설치
npm i swr
혹은 yarn add swr
을 이용해 설치하면 됩니다.
useSWR
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
에 오류가 기록되고요.
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
를 이용해 url
에 get
요청을 보내 데이터를 받아옵니다. 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>
위와 같이 표현하고자 하는 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
라는 캐시 무효 전략을 이용해 지속적이고 자동으로 최신화된 데이터를 가져오는 멋진 도구입니다. 자세한 내용은 추후 추가해보겠습니다.
코드 원본은 여기를 참고해 주시면 됩니다.