
useEffect() 로 단순하게 axios나 fetch를 이용하면, 자식에게 정보를 전달하기 위해서 이러한 로직을 최상단 컴포넌트 에서 진행해야한다. 그리고 필요한 모든 자식에게 정보를 전달하기 위해 props로 넘겨줘야 한다. 하지만 이는 props drilling을 유발할 수 있으며 유지보수가 어려워질 수 있다. react에서 제공하는 ContextAPI를 이용하여 props drilling을 피할 수 있지만 비효율적인 re-render가 발생할 수 있다. swr과 react-query는 이러한 문제를 간단하게 해결해준다. 필요하면 어디서든 꺼내서 쓰고, 데이터가 없으면 fetching해서 쓰고, 데이터가 기존에 있으면 caching된 것을 쓰면 된다.{ refreshInterval: 1000 } (1초) 를 주면 된다. 그러나 개발자가 이러한 자동 갱신 기능을 필요로 하지 않으면 이 역시 option으로 주거나, 혹은 useSWRImmutable() 을 사용한다. 그리고 이러한 option을 전역적으로 설정하여 사용하고 싶으면 useSWRConfig() 사용할 수 있다.즉 주요 기능을 정리하면, SWR은 데이터를 가져오는 것을 목적으로하는 데이터 패칭기능이고, 그 전에 cache된 데이터가 있으면 그것을 share하고, 그 기준은
key값이다.
errorRetryInterval
error가 발생하면, swr은 자동으로 error 재시도를 적용한다. 이 로직은 지수 백오프 알고리즘을 적용하기에, 에러 재시도 속도는 갈수록 느려진다. 계속 재시도하면 리소스가 낭비될 수 있기 때문이다. 이러한 기능도 onErrorRetry 옵션을 통해 오버라이드할 수 있다. 또한 error 재시도 기능을 사용하지 않으려면 shouldRetryOnError 옵션을 false로 설정하면 된다.
errorRetryCount
최대 에러 재시도 수를 정할 수 있다.
onSuccess
데이터 패칭이 성공하고 종료되었을 경우의 호출되는 콜백 함수이다.
이러한 custom 옵션에는 매우 다양한 종류들이 더 있다. 공식문서에서 찾아볼 수 있다.
또한 useSWR은 알아서 요청하는 hook이기에 개발자가 관장하기 쉽지 않다. 개발자가 이 hook이 언제 요청되는지 인지하기 힘들다. 또한, 개발 도중 useSWR 훅이 자동으로 알아서 호출되어야 하는 것이 아닌 특정 시점에 정확히 호출되어야 하는 상황이 생기면, 이를 조건부로 hook을 호출할 수 있다.
// 방법1
const { data: user1 } = useSWR(userData ? '/api/user/id' : null, fetcher);
// 방법2
const { data: user2 } = useSWR(() => userData ? '/api/user/id' : null, fetcher);
// 함수로 전달할 때, swr은 함수의 return값을 key로 사용한다
useSWR사이에서 data끼리 의존하는 것 또한 가능하다.
function MyProjects () {
const { data: user } = useSWR('/api/user', fetcher1);
const { data: projects } = useSWR(() => `/api/projects?uid=${user.id}`, fetcher2);
/* 함수를 전달할 때, SWR은 반환 값을 `key`로 사용한다.
첫번 째 swr이 falsy를 던지거나 반환한다면, 두번 째 SWR은 일부 의존성이 준비되지 않은 것을 알게 된다.
이 예시의 경우 `user.id`는 `user`가 로드되지 않았을 때, 로딩 혹은 에러를 던진다.*/
if (!projects) return 'loading...'
return 'You have ' + projects.length + ' projects'
}
어떤 상황에서는 fetcher함수에 여러 인자를 사용해야하는 다중 인자 상황이 올 수 있다. 예를 들어 다음과 같은 hook은 올바르지 않다.
useSWR('/api/user', url => fetchWithToken(url, token));
데이터의 식별자로서 키는 '/api/user' 이고, 이는 이후 어떤 token이 적용되는 key값은 유일하기에 swr은 이를 다른 데이터로 인식하지 못한다.
이럴 경우에는, key 값을 배열로 주입한다.
useSWR(['/api/user', token], url=> fetchWithToken(url, token));
이렇게 하면 token의 값에 따라 다른 key로 인식되어 올바르게 로직이 작동한다.
또한 이전 버전에서는 key값으로 객체를 전달할 수 없었지만, 이제는 바로 전달할 수 있으며 fetcher가 그 객체를 받는다.
const { data: orders } = useSWR({ url: '/api/orders', args: user }, fetcher);