닫기
React Query vs SWR

React Query vs SWR

Chelsea
December 29, 2021
TECH

리액트 개발자라면 누구나 Redux, MobX 등의 상태 관리 라이브러리를 사용해 본 경험이 있을 것이다. 이 라이브러리들은 클라이언트 상태 관리에는 유용하지만, 서버 상태와 동기화되지 않기 때문에 프론트엔드 개발자들은 직접 상태를 업데이트해 줘야 하는 불편함이 있다.

이러한 불편함을 해소하기 위해 등장한 새로운 방식의 라이브러리가 바로 React Query와 SWR이다. 우리 회사의 프로덕트 중 하나인 ‘레버’에서는 상태 관리를 위해 SWR을 사용하고 있는데, 개인적으로 공부하던 중 요즘 트렌드는 React Query라는 것을 알게 되었다.

React Query와 SWR의 npm 다운로드 수 비교

2021년 1월까지만 해도 SWR이 미세한 차이로 앞서나가고 있었으나, 현재는 React Query의 다운로드 수가 우세한 상황이다. 같은 동기를 가지고 개발된 두 라이브러리는 어떤 차이가 있을까?

Overview

React Query

React Query는 리액트 애플리케이션에 서버 상태를 가져오고, 캐싱하고, 동기화하고, 업데이트하는 것을 쉽게 해 준다.

SWR

SWR은 먼저 캐시에서 데이터를 반환한 다음, 서버에 데이터를 가져오는 요청을 보내고, 마지막으로 최신 데이터를 제공하는 전략이다.

SWR과 React Query 공식 문서에 나와 있는 짤막한 소개다. 둘의 개념 자체는 비슷해 보인다. 둘을 직접 사용해 보며 차이점을 알아보자. (SWR v1.1.1, React Query v3.34.2 기준)

Basic Usage

아래 예제를 통해 기본적인 사용법을 비교해 보자.

SWR

import useSWR from "swr";
const App = () => (
  <div>
    <SWRProfile />
  </div>
);
const SWRProfile = () => {
  const {data, error} = useSWR("https://61b88c9d64e4a10017d19053.mockapi.io/user", url =>
    fetch(url).then(res => res.json())
  );
  if (error) return <div>failed to load</div>;
  if (!data) return <div>loading...</div>;
  return <Profile library="SWR" data={data} />;
}
const Profile = ({library, data}) => (
  <div>
    <h1>Users from {library}</h1>
    {data.map(user => <p>{user.level} developer <strong>{user.name}</strong></p>)}
  </div>
)
export default App;

React Query

import { QueryClient, QueryClientProvider, useQuery } from "react-query";
const queryClient = new QueryClient();
const url = "https://61b88c9d64e4a10017d19053.mockapi.io/user";
const App = () => (
  <div>
    <QueryClientProvider client={queryClient}>
      <ReactQueryProfile />
    </QueryClientProvider>
  </div>
);
const ReactQueryProfile = () => {
  const {isLoading, error, data, isFetching} = useQuery("users", () =>
    fetch("https://61b88c9d64e4a10017d19053.mockapi.io/user").then(res => res.json())
  );
  if (error) return <div>failed to load</div>;
  if (isLoading) return <div>loading...</div>;
  return <Profile library="React Query" data={data} />;
}
const Profile = ({library, data}) => (
  <div>
    <h1>Users from {library}</h1>
    {data.map(user => <p>{user.level} developer <strong>{user.name}</strong></p>)}
  </div>
)
export default App;

Provider

SWR은 별도의 Provider 없이 컴포넌트에서 바로 사용할 수 있지만, React Query는 Provider로 컴포넌트를 감싸지 않을 경우 에러가 발생한다.

Fetcher

useSWR, useQuery 모두 두 번째 인자로 fetcher를 받는다. 차이점이 있다면 SWR은 fetcher의 인자로 useSWR의 첫 번째 인자를 넘겨 주고, useQuery는 fetcher에 url을 직접 전달해야 한다는 점이다. 또한 SWR은 전역 설정을 통해 fetcher를 정해 둘 수 있지만, React Query는 항상 두 번째 인자에 fetcher를 넘겨 줘야 한다.

Status

SWR은 isValidating을 이용해 상태를 표현하는 데 반해, React Query는 isLoading, isFetching을 통해 데이터의 상태를 보여 준다. 특히 isFetching은 첫 번째 로드를 제외한 데이터 업데이트 시의 상태를 나타내는 값으로 모든 데이터 로드 상태를 나타내는 isValidating과 구별된다.

Mutation

SWR과 React Query는 모두 뮤테이션이라는 개념을 가지고 있다. 하지만 두 라이브러리에게 있어 이 개념은 다르게 작용한다. 둘 다 변형시킨다는 의미에서는 같지만, React Query의 뮤테이션은 post/patch/put/delete를 통해 서버의 상태를 변형시키는 것이고, SWR의 뮤테이션은 useSWR()을 통해 받아온 데이터를 클라이언트 사이드에서 변형시켜 업데이트해 주는 개념이다.

Devtools

React Query는 react-query/devtools를 통해 devtools를 제공한다. 사용 방법은 아래와 같다.

import { ReactQueryDevtools } from 'react-query/devtools'
function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <ReactQueryDevtools initialIsOpen={false} />
    </QueryClientProvider>
  )
}

process.env.NODE_ENV가 development일 때만 보이는 컴포넌트이므로 걱정할 것은 없다. ReactQueryDevtools는 왼쪽 하단에 토글 버튼이 위치하는 방식이며, embed 방식으로 사용하고 싶다면 ReactQueryDevtoolsPanel을 사용하면 된다.

SWR 또한 devtools를 사용할 수 있으나, 공식적으로 제공되고 있지는 않아 서드 파티 라이브러리를 사용해야 한다.

Bi-directional Infinite Queries

페이지네이션과 무한 스크롤 같은 UI를 사용할 때 SWR과 React Query 모두 도움이 된다. 하지만 SWR은 이전 페이지의 데이터를 불러 오려면 유저가 부가적인 코드를 작성해야 한다. 그에 반해 React Query는 getPreviousPageParam, fetchPreviousPage, hasPreviousPage, isFetchingPreviousPage 프로퍼티들을 통해 이전 페이지 데이터를 쉽게 핸들링할 수 있다.

Lagged Query Data

React Query는 다음 데이터를 불러오기까지 현재 데이터를 표시해 준다. 예를 들면 페이지네이션에서 다음 페이지를 불러오는 동안 보여 줄 데이터가 없을 때 현재 캐싱되어 있는 데이터를 자동으로 렌더링하는 것이다. 이는 페이지네이션에서 꽤 유용하게 사용된다. SWR이 기본적으로 지원하고 있는 기능은 아니지만 부가적인 코드 작성을 통해 구현 가능하다.

Offline Mutation

위에서 말했듯 SWR과 React Query의 뮤테이션은 다르게 작동한다. React Query에서는 오프라인 상태에서 뮤테이션을 시도했을 때 해당 요청을 잠시 멈췄다가 온라인 상태가 되면 요청을 재시도한다. 이러한 API 요청을 멈췄다가 다시 시도해 서버의 데이터를 변경하는 것은 SWR에는 없는 기능이다.

Selectors

import { useQuery } from 'react-query'
function User() {
  const { data } = useQuery('user', fetchUser, {
    select: user => user.username,
  })
  return <div>Username: {data}</div>
}

위의 코드는 React Query에서 selector를 이용해 쿼리 결과의 부분을 추출하는 코드다. React Query에만 있고 SWR에는 없는 기능이다.

Data Optimization

React Query는 렌더링 퍼포먼스 측면에서도 뛰어난 라이브러리다. 쿼리가 업데이트될 때만 컴포넌트를 업데이트한다. 또한 여러 컴포넌트가 같은 쿼리를 사용하고 있을 때는 한꺼번에 묶어 업데이트해 준다. 이 항목은 SWR에는 해당되지 않는다.

Auto Garbage Collection

React Query는 쿼리가 지정된 시간(설정하지 않을 경우 기본 5분) 동안 쿼리가 사용되지 않을 경우 자동으로 Garbage Collection을 지원한다. 이 또한 SWR에는 해당되지 않는 항목이다.

Prefetching APIs

React Query는 prefetchQuery를 통해 데이터 프리패칭을 다룰 수 있다. SWR에서 불가능한 부분은 아니며, 다른 방식으로 코드를 작성해 같은 효과를 볼 수 있다. React Query에서는 별도의 API를 지원한다는 부분이 차이점이다.

Query Cancellation

기본적으로 프로미스가 처리되기 전에 마운트가 해제되거나 사용되지 않는 쿼리는 취소되지 않는다. 그러나 AbortSignal을 사용하거나 프로미스에 cancel 함수를 적용하면 프로미스가 취소됨에 따라 쿼리도 함께 취소된다. 쿼리가 취소되면 해당 상태가 이전으로 돌아간다. 이 기능은 React Query에서만 지원되고 있다.

이외에도 React Query에서만 지원하는 많은 기능들이 더 있다. 자세히 알아보고 싶다면 링크를 눌러 확인해 보자.

결론

React Query를 공부하기 전, SWR과의 차이점을 알아보기 위해 이것저것 검색했지만 마땅한 자료를 찾기 힘들었다. 당시 참고했던 글 중 하나는 2020년 1월에 작성된 글이었는데, 그때까지만 해도 React Query의 버전이 상당히 낮아 SWR과 비교 자체가 안 되는 수준이었다. 하지만 React Query는 점차 발전해 왔고, 현재는 프론트엔드 개발자들의 높은 선호도뿐만 아니라 지원하는 기능들의 수준도 탁월하다. 개인적으로 렌더링 퍼포먼스를 높이기 위해 데이터를 최적화한 점과 자동으로 가비지 컬렉션을 지원한다는 점에서 크게 감명받았다. 이제는 React Query의 시대를 기대해 봐도 괜찮지 않을까?

Reference

닫기

개인정보 처리방침

<매드업>은 개인정보보호법에 따라 이용자의 개인정보 보호 및 권익을 보호하고 개인정보와 관련한 이용자의 고충을 원활하게 처리할 수 있도록 다음과 같은 처리방침을 두고 있습니다.

<매드업>은 회사는 개인정보처리방침을 개정하는 경우 웹사이트 공지사항(또는 개별공지)을 통하여 공지할 것입니다.

○ 본 방침은 2020년 1월 15일부터 시행됩니다.

개인정보의 처리 목적 <매드업>은 개인정보를 다음의 목적을 위해 처리합니다. 처리한 개인정보는 다음의 목적 이외의 용도로는 사용되지 않으며 이용 목적이 변경될 시에는 사전동의를 구할 예정입니다.

가. 홈페이지 회원가입 및 관리 회원 가입의사 확인, 회원제 서비스 제공에 따른 본인 식별·인증, 회원자격 유지·관리, 제한적 본인확인제 시행에 따른 본인확인, 서비스 부정이용 방지, 만14세 미만 아동 개인정보 수집 시 법정대리인 동의 여부 확인, 각종 고지·통지, 고충처리, 분쟁 조정을 위한 기록 보존 등을 목적으로 개인정보를 처리합니다.

나. 민원사무 처리 민원인의 신원 확인, 민원사항 확인, 사실조사를 위한 연락·통지, 처리결과 통보 등을 목적으로 개인정보를 처리합니다.

다. 재화 또는 서비스 제공 물품배송, 서비스 제공, 청구서 발송, 콘텐츠 제공, 맞춤 서비스 제공, 본인인증, 연령인증, 요금결제·정산 등을 목적으로 개인정보를 처리합니다.

라. 마케팅 및 광고에의 활용 신규 서비스(제품) 개발 및 맞춤 서비스 제공, 이벤트 및 광고성 정보 제공 및 참여기회 제공 , 인구통계학적 특성에 따른 서비스 제공 및 광고 게재 , 서비스의 유효성 확인, 접속빈도 파악 또는 회원의 서비스 이용에 대한 통계 등을 목적으로 개인정보를 처리합니다.

 

 

개인정보 파일 현황

가. 개인정보 파일명 : 개인정보 처리방침

개인정보 항목 : 이메일, 휴대전화번호, 비밀번호, 이름, 업체명, 제목, 광고 예산, 내용, 사업자 등록 번호, 신용카드정보, 은행계좌정보, 예금주, 생년월일, 서비스 이용 기록, 접속 로그, 쿠키, 접속 IP 정보, 결제기록

수집방법 : 홈페이지, 계약서

보유근거 : 홈페이지 회원정보 수집 등에 관한 기록

보유기간 : 5년

관련법령 : 대금결제 및 재화 등의 공급에 관한 기록 : 5년

개인정보의 처리 및 보유 기간 ① <매드업>은 법령에 따른 개인정보 보유·이용기간 또는 정보주체로부터 개인정보를 수집 시에 동의 받은 개인정보 보유,이용기간 내에서 개인정보를 처리,보유합니다. ② 각각의 개인정보 처리 및 보유 기간은 다음과 같습니다.

 

가. <홈페이지 회원가입 및 관리> <홈페이지 회원가입 및 관리>와 관련한 개인정보는 수집.이용에 관한 동의일로부터<5년>까지 위 이용목적을 위하여 보유.이용됩니다.

보유근거 : 홈페이지 회원정보 수집 등에 관한 기록

관련법령 : 대금결제 및 재화 등의 공급에 관한 기록 : 5년

예외사유 :

 

나. <재화 또는 서비스 제공> <재화 또는 서비스 제공>와 관련한 개인정보는 수집.이용에 관한 동의일로부터<5년>까지 위 이용목적을 위하여 보유.이용됩니다.

보유근거 : 계약 또는 청약철회 등에 관한 기록

관련법령 : 계약 또는 청약철회 등에 관한 기록 : 5년

예외사유 :

 

다. <마케팅 및 광고에의 활용> <마케팅 및 광고에의 활용>와 관련한 개인정보는 수집.이용에 관한 동의일로부터<3년>까지 위 이용목적을 위하여 보유.이용됩니다.

보유근거 : 전자상거래등에서의 소비자보호에 관한 법률

관련법령 : 소비자의 불만 또는 분쟁처리에 관한 기록 : 3년

예외사유 :

 

 

정보 주체와 법정대리인의 권리·의무 및 그 행사방법 이용자는 개인정보주체로써 다음과 같은 권리를 행사할 수 있습니다.

① 정보주체는 매드업에 대해 언제든지 개인정보 열람,정정,삭제,처리 정지 요구 등의 권리를 행사할 수 있습니다.

② 제1항에 따른 권리 행사는 매드업에 대해 개인정보 보호법 시행령 제41조제1항에 따라 서면, 전자우편, 모사전송(FAX) 등을 통하여 하실 수 있으며 매드업은 이에 대해 지체 없이 조치하겠습니다.

③ 제1항에 따른 권리 행사는 정보주체의 법정대리인이나 위임을 받은 자 등 대리인을 통하여 하실 수 있습니다. 이 경우 개인정보 보호법 시행규칙 별지 제11호 서식에 따른 위임장을 제출하셔야 합니다.

④ 개인정보 열람 및 처리 정지 요구는 개인정보보호법 제35조 제5항, 제37조 제2항에 의하여 정보주체의 권리가 제한 될 수 있습니다.

⑤ 개인정보의 정정 및 삭제 요구는 다른 법령에서 그 개인정보가 수집 대상으로 명시되어 있는 경우에는 그 삭제를 요구할 수 없습니다.

⑥ 매드업은 정보주체 권리에 따른 열람의 요구, 정정·삭제의 요구, 처리 정지의 요구 시 열람 등 요구를 한 자가 본인이거나 정당한 대리인인지를 확인합니다.

 

 

처리하는 개인정보의 항목 작성

① <매드업>은 다음의 개인정보 항목을 처리하고 있습니다.

 

가. <홈페이지 문의 및 관리>

필수항목 : 업체명, 이메일, 제목, 연락처, 광고 예산, 내용, 휴대전화번호, 비밀번호, 이름, 서비스 이용 기록, 접속 로그, 쿠키, 접속 IP 정보

선택항목 : 프로필 사진

 

나. <재화 또는 서비스 제공>

필수항목 : 업체명, 이메일, 제목, 연락처, 광고 예산, 내용, 비밀번호, 이름, 회사명, 사업자 등록 번호, 신용카드정보, 은행계좌정보, 예금주, 생년월일, 서비스 이용 기록, 접속 로그, 쿠키, 접속 IP 정보, 결제기록

선택항목 :

 

다. <마케팅 및 광고에의 활용>

필수항목 : 업체명, 이메일, 제목, 연락처, 광고 예산, 내용, 휴대전화번호, 이름, 서비스 이용 기록, 접속 로그, 쿠키, 접속 IP 정보

선택항목 :

 

개인정보의 파기<매드업>은 원칙적으로 개인정보 처리 목적이 달성된 경우에는 지체없이 해당 개인정보를 파기합니다. 파기의 절차, 기한 및 방법은 다음과 같습니다.

 

 

파기절차

이용자가 입력한 정보는 목적 달성 후 별도의 DB에 옮겨져(종이의 경우 별도의 서류) 내부 방침 및 기타 관련 법령에 따라 일정기간 저장된 후 혹은 즉시 파기됩니다. 이 때, DB로 옮겨진 개인정보는 법률에 의한 경우가 아니고서는 다른 목적으로 이용되지 않습니다.

 

파기기한

이용자의 개인정보는 개인정보의 보유기간이 경과된 경우에는 보유기간의 종료일로부터 5일 이내에, 개인정보의 처리 목적 달성, 해당 서비스의 폐지, 사업의 종료 등 그 개인정보가 불필요하게 되었을 때에는 개인정보의 처리가 불필요한 것으로 인정되는 날로부터 5일 이내에 그 개인정보를 파기합니다.

파기방법

전자적 파일 형태의 정보는 기록을 재생할 수 없는 기술적 방법을 사용합니다. 종이에 출력된 개인정보는 분쇄기로 분쇄하거나 소각을 통하여 파기합니다.

 

개인정보 자동 수집 장치의 설치•운영 및 거부에 관한 사항

① 매드업은 개별적인 맞춤서비스를 제공하기 위해 이용 정보를 저장하고 수시로 불러오는 ‘쿠키(cookie)’를 사용합니다.

② 쿠키는 웹사이트를 운영하는데 이용되는 서버(http)가 이용자의 컴퓨터 브라우저에게 보내는 소량의 정보이며 이용자들의 PC 컴퓨터 내의 하드디스크에 저장되기도 합니다.

가. 쿠키의 사용 목적 : 이용자가 방문한 각 서비스와 웹 사이트들에 대한 방문 및 이용형태, 인기 검색어, 보안접속 여부, 등을 파악하여 이용자에게 최적화된 정보 제공을 위해 사용됩니다.

나. 쿠키의 설치•운영 및 거부 : 웹브라우저 상단의 도구>인터넷 옵션>개인정보 메뉴의 옵션 설정을 통해 쿠키 저장을 거부 할 수 있습니다.

다. 쿠키 저장을 거부할 경우 맞춤형 서비스 이용에 어려움이 발생할 수 있습니다.

 

 

개인정보 보호책임자 작성

① 매드업은 개인정보 처리에 관한 업무를 총괄해서 책임지고, 개인정보 처리와 관련한 정보주체의 불만처리 및 피해구제 등을 위하여 아래와 같이 개인정보 보호책임자를 지정하고 있습니다.

 

▶ 개인정보 보호책임자

성명 : 강남석

직책 : CFO

직급 : CFO

연락처 : 02-1522-1060, contact@madup.com

※ 개인정보 보호 담당부서로 연결됩니다.

 

▶ 개인정보 보호 담당부서

부서명 : General Affairs Team

담당자 : 민상준

연락처 : 02-1522-1060, contact@madup.com

 

② 정보 주체께서는 매드업의 서비스(또는 사업)을 이용하시면서 발생한 모든 개인정보 보호 관련 문의, 불만처리, 피해구제 등에 관한 사항을 개인정보 보호책임자 및 담당부서로 문의하실 수 있습니다. 매드업은 정보주체의 문의에 대해 지체 없이 답변 및 처리해드릴 것입니다.

 

 

개인정보 처리방침 변경

① 이 개인정보처리방침은 시행일로부터 적용되며, 법령 및 방침에 따른 변경 내용의 추가, 삭제 및 정정이 있는 경우에는 변경사항의 시행 7일 전부터 공지사항을 통하여 고지할 것입니다.

 

 

개인정보의 안전성 확보 조치 <매드업>은 개인정보보호법 제29조에 따라 다음과 같이 안전성 확보에 필요한 기술적/관리적 및 물리적 조치를 하고 있습니다.

가. 정기적인 자체 감사 실시 개인정보 취급 관련 안정성 확보를 위해 정기적(분기 1회)으로 자체 감사를 실시하고 있습니다.

나. 개인정보 취급 직원의 최소화 및 교육 개인정보를 취급하는 직원을 지정하고 담당자에 한정시켜 최소화 하여 개인정보를 관리하는 대책을 시행하고 있습니다.

다. 내부관리계획의 수립 및 시행 개인정보의 안전한 처리를 위하여 내부관리계획을 수립하고 시행하고 있습니다.

라. 해킹 등에 대비한 기술적 대책 <매드업>은 해킹이나 컴퓨터 바이러스 등에 의한 개인정보 유출 및 훼손을 막기 위하여 보안프로그램을 설치하고 주기적인 갱신·점검을 하며 외부로부터 접근이 통제된 구역에 시스템을 설치하고 기술적/물리적으로 감시 및 차단하고 있습니다.

마. 개인정보의 암호화 이용자의 개인정보는 비밀번호는 암호화 되어 저장 및 관리되고 있어, 본인만이 알 수 있으며 중요한 데이터는 파일 및 전송 데이터를 암호화 하거나 파일 잠금 기능을 사용하는 등의 별도 보안기능을 사용하고 있습니다.

바. 접속 기록의 보관 및 위변조 방지 개인정보처리시스템에 접속한 기록을 최소 6개월 이상 보관, 관리하고 있으며, 접속 기록이 위변조 및 도난, 분실되지 않도록 보안기능 사용하고 있습니다.

사. 개인정보에 대한 접근 제한 개인정보를 처리하는 데이터베이스시스템에 대한 접근 권한의 부여,변경,말소를 통하여 개인정보에 대한 접근통제를 위하여 필요한 조치를 하고 있으며 침입차단시스템을 이용하여 외부로부터의 무단 접근을 통제하고 있습니다.

아. 문서 보안을 위한 잠금 장치 사용 개인정보가 포함된 서류, 보조저장매체 등을 잠금 장치가 있는 안전한 장소에 보관하고 있습니다.

자. 비인가자에 대한 출입 통제 개인정보를 보관하고 있는 물리적 보관 장소를 별도로 두고 이에 대해 출입통제 절차를 수립, 운영하고 있습니다.