[React] SWR
참고 문서
테스트 환경 정보
- x.x.x
개요
SWR은 먼저 캐시(stale)로부터 데이터를 반환한 후, fetch 요청(revalidate)을 하고, 최종적으로 최신화된 데이터를 가져오는 전략입니다.
SWR은 Next.js 팀이 만든 리액트 훅으로 useEffect 훅을 대체하여 사용할 수 있다.
'SWR'이란 이름은 HTTP RFC 5861의 HTTP 캐시 무효 전략인 stale-while-revalidate에서 유래되었다고 한다.
import React, {useEffect} from 'react';
import useSWR from 'swr';
// 모의 fetcher 함수: 2초 후에 데이터 반환
const fetcher = async (key) => {
return new Promise((resolve) => {
setTimeout(() => {
resolve({
id: 1,
name: 'Test User',
email: 'test@example.com',
});
}, 2000);
});
};
export default function UseSwrTest() {
const { data, error, isLoading } = useSWR('my-awesome-key', fetcher);
return (
<section>
<h2>useSWR Test</h2>
{
error ? (
<div>failed to load</div>
) : isLoading ? (
<div>loading...</div>
) : (
<>
<p>hello, {data?.name}!</p>
<p>Email: {data?.email}</p>
</>
)
}
</section>
);
}
useSWR()
const { data, error, isLoading, isValidating, mutate } = useSWR(key, fetcher, options)
key: 요청을 구분하는 고유한 키 값fetcher: 실제 데이터를 가져오는 비동기 콜백 함수. 이 함수의 반환 타입은Promise여야 하고, 첫 번째 인자에key로 지정한 값이 그대로 전달된다(공식 가이드에선url이라 표시함).fetcher는 선택 사항이라 생략할 수 있는데, 이 경우fallback이나fallbackData로 초기 데이터를 설정하고,mutate()함수를 통해 데이터를 변경해야 한다.options: 선택 사항. 생략하면 기본 설정으로 작동함.suspense: 기본값false.fetcher(args):revalidateIfStale: 캐시된 데이터가 '오래되었다(stale)'고 판단될 때 백그라운드에서 데이터를 자동으로 재검증할지 여부. 기본값은true.revalidateOnMount: 컴포넌트가 마운트될 때마다 데이터를 재검증할지 여부. 기본값은true.revalidateOnFocus: 브라우저 창에 다시 포커스가 생겼을 때 데이터를 재검증할지 여부. 기본값은true.revalidateOnReconnect: 인터넷이 오프라인이었다가 다시 연결되었을 때 데이터를 재검증할지 여부. 기본값은true.refreshInterval: 밀리초로 지정하는 데이터 갱신 간격. 숫자 혹은 숫자를 반환하는 함수를 지정할 수 있다.0으로 설정하거나 생략하면 비활성화 된다.refreshWhenHidden: 기본값false.refreshWhenOffline: 기본값false.shouldRetryOnError: 기본값true.dedupingInterval: 중복 요청을 방지하는 최소 시간. 이 시간 내에 발생한 요청을 막고 캐시 데이터를 반환한다. 단위는 밀리초,0으로 설정하면 비활성화된다. 생략했을 때의 기본값은2000(2초).focusThrottleInterval: 기본값5000.loadingTimeout: 기본값3000.errorRetryInterval: 기본값5000.errorRetryCount:fallback:fallbackData:keepPreviousData: 기본값false.onLoadingSlow(key, config):onSuccess(data, key, config):onError(err, key, config):onErrorRetry(err, key, config, revalidate, revalidateOps):onDiscarded(key):compare(a, b):isPaused():use:
반환값은:
data:error:isLoading:isValidating:mutate:fetcher를 사용하지 않고 수동으로 데이터를 변경하는 함수.
키 외에 다른 인수에도 의존하는 경우
SWR은 키를 기준으로 데이터 고유성을 판단한다. 그런데 만약 키 말고도 호출에 필요한 인수가 더 있다면, 아래처럼 배열을 사용하여 키에 해당 인수를 포함해야 한다:
// 코드 출처: https://swr.vercel.app/docs/arguments#multiple-arguments
// ❌ 잘못된 방법 - token이 바뀌어도 같은 캐시 사용
useSWR('my-awesome-key', key => fetchWithToken(key, token))
// ✅ 올바른 방법 - token마다 별도 캐시
const {data: user} = useSWR(['my-awesome-key', token], ([key, token]) => fetchWithToken(key, token))
예를 들어, 아래처럼 특정 상위 코드와 연관된 코드 항목들을 검색한다고 할 때, 배열로 키를 정의하면 전달한 상위 코드마다 캐시가 따로 적용된다:
function fetchCodeItems(upperCode) {
return fetch(`/system/code-items?code=${upperCode}`);
}
// ... 생략
const {data: response} = useSWR([`my-awesome-key`, upperCode], ([key, upperCode]) => fetchCodeItems(upperCode));
useEffect와 비교
TODO