서론SWR이란?왜 필요한가1. CSR에서 데이터 fetching 로직 단순화2. 캐싱 기반 데이터 전역 관리예시 잠깐! 전시회 상세 페이지3. SWR vs react-query 4. 기타 다양한 옵션들SWR의 사용법 반환값파라미터참고자료
서론
지난 주 회의에서 SWR을 도입할 것을 건의했는데요,
그래서 SWR의 정의, 필요성, 용법 등을 문서로 정리해봤습니다.
우리 프로젝트에 녹여내 설명한 것도 있으니 봐주시면 좋을 것 같습니다.
SWR을 사용하면서 많은 도움이 되기를 바랍니다.
- 기홍

SWR이란?
- Vercel에서 만든 데이터 fetching을 위한 리액트 훅
- Axios를 완전히 대체하는 기술은 아니다. 데이터 fetch, 즉 GET에 특화된 라이브러리라고 할 수 있다. 그 외 POST, PUT 등은 axios를 그대로 사용할 예정이다.
왜 필요한가
1. CSR에서 데이터 fetching 로직 단순화
아래는 우리 프로젝트의 유저 정보 조회 API이다.
// 기존 방식 const [userInfo, setUserInfo] = useState(); useEffect(() => { (async () => { const data = await userAPI.getUserInfo(Number(id)).then((res) => res.data.data); setUserInfo(data); })(); }, []);
// SWR 사용 const { data: userInfo } = useSWR(`/api/v1/users/${id}/info`);
훨씬 명확하고 간단하며, 선언적임을 알 수 있다. 클린코드 만세
2. 캐싱 기반 데이터 전역 관리
useSWR('/api/signin', Fetcher)
를 호출했다면 무슨 일이 일어나는가?- '/api/signin'라는 주소에서 Fetcher라는 함수를 실행한다.
- 함수 실행 결과로 데이터를 받아와서, 데이터를 캐시한다.
캐시?
한 번 fetch한 데이터를 내부적으로 캐시한다.
즉, 클라이언트에 잠시 저장을 해둔다는 의미이다.
다른 컴포넌트에서 동일한 상태를 사용하고자 할 경우, 캐시해둔 상태를 그대로 리턴한다.
캐싱을 기반으로 데이터를 전역적으로 공유한다는 것이 이 의미이다.
예시
후기 상세페이지에서 후기 단건 조회 API를 사용한다.

후기 수정 페이지에서도 후기 단건 조회 API를 사용한다.
(새로고침이 일어날 수 있으므로 필요하다)

두 페이지(컴포넌트)는 아래와 같은 SWR을 사용한다. key가 동일하다.
useSWR(`/api/v1/reviews/156`)
원격 데이터를 사용하는 서로 다른 컴포넌트가 같은 key를 사용한다면 동일한 상태를 공유한다
잠깐!
현재 axios의 경우, 로그인 여부에 따라 authRequest, unAuthRequest로 다른 요청을 보내고 있다.
이에 따라 응답 데이터가 달라지기 때문이다.
이와 같은 동적인 요청도 useSWR을 통해서 가능하다.
아래는 전역적으로 설정한 SWR 옵션이다.
const swrOptions = { fetcher: async (url: string) => { const isLoggedIn = cookie.load('REFRESH_TOKEN'); const accessToken = cookie.load('ACCESS_TOKEN'); if (isLoggedIn) { const res = await axios.get(`${process.env.NEXT_PUBLIC_API_END_POINT}${url}`, { headers: { accessToken, }, }); return res.data.data; } else { const res = await axios.get(`${process.env.NEXT_PUBLIC_API_END_POINT}${url}`); return res.data.data; } }, };
아래는 ‘후기 단건조회’의 응답 테스트다. useSWR을 사용하였다.
로그인 하지 않은 경우

로그인 한 경우

SWR을 통해서도 인증 여부에 따른 동적인 요청이 가능함을 확인하였다.
그 외에도, Fetcher 함수 및 baseURL을 전역적으로 설정해두었다.
const res = await axios.get(`${process.env.NEXT_PUBLIC_API_END_POINT}${url}`); return res.data.data;
아래 PR에 적용하였다.
사용하는 쪽에서는 Fetcher 함수를 꼭 전달할 필요가 없으며,
예컨대 아래와 같이 사용하면 된다.
const { data, error } = useSWR(`/api/v1/users/${id}/info`);
전시회 상세 페이지
전시회 상세 페이지에서도 SWR을 사용한다면…어떤 효과가 있을까?
id가 152인 전시회 상세 페이지에 들어갔다가, 뒤로가기를 눌러 밖으로 나온 뒤,
해당 전시회 상세 페이지를 다시 들어간다면?
“이미 서버에서 한 번 데이터를 불러왔으므로, 캐시된 데이터를 사용할 수 있다”
3. SWR vs react-query
react-query가 기능에 있어 더 다양하다고 하지만,
Next.js와의 호환성 및 사용의 용이함 측면에서는 SWR이 장점이 있다고 생각한다.
4. 기타 다양한 옵션들
- 포커싱 시 데이터 갱신, 인터벌 시 갱신, 재연결 시 갱신 옵션 등 (서버와의 동기화)
- MUTATE 함수 지원 (필요한 경우, 데이터를 즉시 업데이트할 수 있다)
- SSR, SSG 지원?
SWR의 사용법
const { data, error, isValidating, mutate } = useSWR(key, fetcher, options)
반환값
- data: fetcher 함수가 가져온 데이터 (또는 undefined)
- error: fetcher가 던진 에러 (또는 undefined)
- isValidation: 요청이나 갱신 로딩의 여부
- mutate: 캐시된 데이터를 뮤테이트(데이터 수정, 업데이트)
파라미터
- key: 요청을 위한 고유한 키 문자열 (url, 필수)
- fetcher: key를 받고 데이터를 반환하는 비동기 함수 (필수x)
- options: SWR hook을 위한 옵션 객체 (필수x)