SWR vs React-Query, 서버데이터 관리

Molly·2023년 5월 29일
15

React, Next.js

목록 보기
4/7
post-thumbnail

SWR, React-Query 왜 쓰는걸까?


프론트엔드 개발자라면 '상태(state) 관리'라는 말에 어느정도 익숙할 것이다. 상태 관리를 매우 축약해서 말하자면, 어플리케이션에서 활용되는 데이터들의 형태를 관리한다는 것이다.

React를 기준으로 상태는 일반적으로 세 가지로 구분된다.

  1. 지역 상태 (Local)
  2. 전역 상태 (Global)
  3. 서버 상태 (Server)

1. 지역 상태

-> React Component 내에서만 정의되는 상태로 보통, useState, useRef 등으로 관리된다.

2. 전역 상태

-> Context Proivder의 자식 Component이면, 어디서든 접근 가능한 상태이며, 
React에서는 보통 context api와 useReducer을 통해, 전역 상태를 관리한다. 
(Context api기준 설명이며, 이외에도 Redux, MobX 등도 자주 활용된다) 

3. 서버 상태

-> 서버로부터 받아오는 데이터를 뜻하며, 보통 SWR 혹은 React-Query로 관리한다.

SWR과 React-Query는 서버 상태 관리를 위한 라이브러리이다. 두 라이브러리 모두, 서버 상태를 가져오며(data fetching), 서버데이터의 캐싱, 동기화, 업데이트를 지원한다.



SWR과 React-Query의 비교


1. 기본 개념

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

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

Data fetching 및 기타 기능에 약간의 차이는 있지만, 기능상 어느정도 유사하다는 것을 알 수 있다.


2. 사용법

Next.js 기준으로, SWR과 React-Query의 사용법을 비교해보겠다.

1) SWR

Explore 페이지 컴포넌트


import useSWR from 'swr';
import axios from 'axios;

const fetcher=(url:string)=>axios.get(url).then((res)=>res.data)

function Explore=()=>{

const { data, isValidating,error,mutate } = useSWR(`/api/allassets`,fetcher);

return (
<div>
{data.map(asset=><p>{asset.name}</p>)}
</div>
)}

2) React-Query

_app.tsx

import {
  QueryClient,QueryClientProvider,
} from '@tanstack/react-query'

function App({ Component, pageProps}: AppProps) {
  const [queryClient] = useState(() => new QueryClient());

  return (
    // Provide the client to your App
    <QueryClientProvider client={queryClient}>
          <Component {...pageProps} />
    </QueryClientProvider>
  )
}

Explore 페이지 컴포넌트

import {  useQuery } from '@tanstack/react-query';
import axios from 'axios';

const fetcher= () => {
  return axios.get(`/api/allassets,fetcher');
};

function Explore=()=>{
  const {isLoading, error, data, isFetching} = useQuery("assets",fetcher);

  return (
    <div>
    {data.map(asset=><p>{asset.name}</p>)}
    </div>
)}

눈여겨봐야할, 중요한 차이점으로 React-Query는 Provider을 제공해줘야하고, SWR은 그냥 사용할 수 있다는 것이다. 이외에도, SWR에서는 key를 url로써 fetcher에 넘겨주는 방식이지만, React-Query의 경우는 data fetching을 직접 구현한 fetcher을 넘겨받는다.



3. 주요 기능 차이


Provider의 유무

React-Query는 _app 컴포넌트에 전용 Provider을 wrapping해줘야, 자식 컴포넌트에서 활용 가능한 반면, SWR은 그대로 fetching을 해주면 된다.


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()을 통해 받아온 데이터를 클라이언트 사이드에서 변형시켜 업데이트해 주는 개념이다.


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


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


Selector
React-Query는 서버에서 가져오는 데이터를 fetching 단계에서 결과를 추출할 수 있다.

import {  useQuery } from '@tanstack/react-query';
import axios from 'axios';

const fetcher= () => {
  return axios.get(`/api/allassets,fetcher');
};

function Explore=()=>{
  const {isLoading, error, data, isFetching} = useQuery("assets",fetcher, {
    select: assets=>assets.name
  })

  return (
    <div>
    {data.map(asset=><p>{asset}</p>)}
    </div>
)}

fetcher 뒤에 select를 지정하여 부분 추출이 가능하다.



결론


벨로그에 글을 쓰면서 알게된 SWR과 React-Query간의 성능 차이를 보고 솔직히 조금 놀랐다.
사실, SWR의 간편함이 좋아서 서버 상태에 대부분 SWR을 활용했었는데, 정말 많이 발전한
React-Query를 더욱 활용해봐야겠다는 생각이 많이 들었다.
특히, 컴포넌트의 렌더링에 더욱 신경써야하는 복잡한 어플리케이션의 경우 적극적으로 React-Query를 활용하고자 한다.




참고자료

https://tech.madup.com/react-query-vs-swr/
https://ryuwoongstory.tistory.com/89

profile
Next.js, Typescript, Rust

0개의 댓글