원문 :
https://javascript.plainenglish.io/why-you-should-use-useswr-instead-of-usestate-when-calling-apis-8b6de5dc18fc
https://velog.io/@ysg81/React-useSwr-사용하기
https://github.com/vercel/swr
https://swr.vercel.app/ko/docs/revalidation
SWR이란 무엇인가?
SWR(State While Revalidate)은 서버에서 데이터를 가져오는 데 사용되는 React 후크이다. useState와 useEffect를 사용하지 않고 실시간 데이터를 fetch, 캐싱 또는 re-fetch 할 수 있다. SWR은 캐시에서 데이터를 제공한 다음 검증을 위해 서버를 만들고 일단 완료되면 데이터 일관성을 위해 데이터를 결합한다.
NPM 혹은 YARN 설치 명령을 사용하여 SWR을 설치할 수 있다.
npm i swr
yarn add swr
어떻게 사용 하는가?
SWR은 간단한 React 후크이며 개체 모델의 오류뿐만 아니라 데이터를 반환한다.
import useSWR from 'swr'
function Profile() {
const { data, error } = useSWR('/api/user', fetcher)
if (error) return <div>failed to load</div>
if (!data) return <div>loading...</div>
return <div>hello {data.name}!</div>
}
// or
export const useXXX = () => {
const { data, isValidating, error } = useSWR<ReturnDataType>(
'key', async () => {
// 비동기 통신 부분
const res = await ...
return res.data
},
);
return {
data,
isLoading: isValidating,
error,
};
};
const { data, isValidating, error }
- data는 비동기 통신으로 받아온 데이터이다. 타입스크립트에서 useState 타입을 지정해 주는 것 처럼 간단하게 선언해 줄 수 있다.
- isValidating은 react-query에서 isFetching | isLoading 처럼 fetching 중인지를 알 수 있는 boolean 값이다.
const isLoading = (!data && !error) || isValidating
- 완벽하게 예외를 제거하기 위해서는 위에처럼 error와 data를 모두 고려해서 주면 좋다.
매개변수가 존재할 때는 어떻게 해야 할까?
export const useXXX = (param: string) => {
const { data, isValidating, error } = useSWR<ReturnDataType>(
[param], async () => { // 필요한 param을 넣어주면 된다 이 값이 key 값이 된다.
// 비동기 통신 부분
const res = await axios.get('/api', { param })...
return res.data
},
);
return {
data,
isLoading: isValidating,
error,
};
};
const { data, isLoading, error } = useXXX(param); // hooks처럼 param 값만 넣어주면 된다
Axios를 밖으로 빼서 리팩토링 할 수도 있다.
const fetcher = async() => {
const res = await axios.get(...)
return res.data
}
export const useXXX = () => {
const { data, isValidating, error } = useSWR<ReturnDataType>(
'key', fetcher
)
return {
data,
isLoading: isValidating,
error,
};
};
// 매개변수가 있을 경우
const fetcher = async(param1: string) => {
const res = await axios.get(...)
return res.data
}
export const useXXX = () => {
const { data, isValidating, error } = useSWR<ReturnDataType>(
[param1],
fetcher
)
return {
data,
isLoading: isValidating,
error,
};
};
- 보통 param 부분에 url을 많이 넣어주기 때문에 이 url이 key값이 된다.
- 취향차이로 fetcher를 api로 useXXX를 hooks 폴더로 관리하면 유지보수면에서도 편리하겠다.
SWR에서 제공하는 기능
SWR은 더 나은 사용자 경험으로 애플리케이션을 구축할 수 있도록 성능, 정확성 및 안정성을 위한 다양한 기능을 제공한다.
성능
SWR은 고성능을 염두에 두고 Next.JS 팀에 의해 구축되었다. 불필요한 네트워크를 건너뛰는 캐싱 시스템과 중복 제거 시스템을 구축했다. React 후크이기 때문에 네트워크 호출로 인한 불필요한 재 렌더링을 피할 수 있다.
따라서 이점은 다음과 같다.
- 불필요한 요청 없음
- 불필요한 재렌더링 없음
- 불필요한 코드를 가져오지 않음
Prefetching Data
기본적으로 <link ref="preload" href="..."/>를 추가하여 데이터를 미리 가져올 수 있다. 그러나 일부에서는 데이터를 프로그래밍 방식으로 미리 가져와야 한다.
SWR은 이러한 프로그래밍 방식으로 데이터를 미리 가져오는 옵션을 제공한다.
에러 핸들링
오류 처리는 모든 응용 프로그램에서 더 나은 사용자 경험을 제공하는 데 중요하다. SWR 는 전역적으로 오류를 처리하는 옵션을 제공하여 최종 빌드에서 많은 코드를 줄일 수 있다.
import React from "react";
import { SWRConfig } from "swr";
const App = () => {
return (
<SWRConfig
value={{
onError: (error, key) => {
if (error.status !== 403 && error.status !== 404) {
// We can send the error to Sentry,
// or show a notification UI.
}
}
}}
>
<MyApp />
</SWRConfig>
)
}
SWR을(를) 사용해 보자. 여러 가지 방법으로 응용 프로그램 성능이 향상된다.
revalidateOnFocus
브라우저 창을 다른 곳으로 focus를 옮기고 돌아오면 데이터가 재 랜더링이 되는 걸 방지하고 싶으면 revalidateOnFocus 옵션으로 막을 수 있다.
export const useXXX = () => {
const { data, isValidating, error } = useSWR<ReturnDataType>(
[param1],
fetcher,
// 포커싱 옵션
{ revalidateOnFocus: false },
)
return {
data,
isLoading: isValidating,
error,
};
};
조건부 랜더링
어떠한 변수값에 따라 swr을 실행시키고 싶으면
export const useXXX = (isTrigger: boolean) => {
const { data, isValidating, error } = useSWR<ReturnDataType>(
[param1],
// 조건부 랜더링
isTrigger ? fetcher : null,
)
return {
data,
isLoading: isValidating,
error,
};
};
isTrigger가 true일 때만 즉, 원하는 시점에 실행시킬 수도 있다.
마무리
React 애플리케이션에서 우리는 일반적으로 데이터를 가져오고 콘텐츠를 렌더링하는데 useState 와 fetch를 사용 한다. useSWR를 사용하면 캐시에서 데이터를 제공하여 성능을 향상시킨 다음 확인을 위해 호출을 전송하고 마지막으로 데이터 일관성을 위해 두 데이터 소스를 결합한다.
다음에는 React-Query와 비교해 보는 공부를 해 봐야겠다.
'Front-End > React' 카테고리의 다른 글
엑셀 다운로드 (0) | 2023.07.02 |
---|---|
useSWR vs React(TanStack) Query를 비교해보자 (2) | 2023.01.10 |
[React] useEffect와 sideEffect (1) | 2022.08.22 |
[React, JS] 비동기 동기 처리 (0) | 2022.08.11 |
[React] 상태관리 (Local State, Global State, Cross Component State) (0) | 2022.08.10 |