[React] SWR이 무엇인가요?

우선 SWR을 알아보기 앞서 캐시에 대해서 알아보겠습니다.

❓캐시란 무엇인가

캐시는 데이터를 일시적으로 저장하는 메모리를 가리키는 용어입니다.

한 번의 요청에 비용이 큰 경우, 여러 번 요청을 하는 것 보다, 한 번의 요청 이후 캐시에 저장하여 재사용 하기 위한 전략입니다.

❓SWR이 무엇인가

SWR은 Stale-While-Revalidate의 약자로 HTTP 캐시 무효 전략을 뜻합니다.

SWR은 우선적으로 캐시로 부터 데이터를 반환한 후, fetch 요청(Revalidate)이 필요한지 확인하고 요청을 합니다.

즉 캐시에 있는 데이터로 처리할 수 있다면, 굳이 요청을 하지 않는 것이죠.

그리고 반대로 사용자가 원하는 순간에 요청을 보내 새로 데이터를 받을 수 있습니다.

이를 통해 컴포넌트는 지속적으로 자동 업데이트 되어 사용자 경험을 향상시킬 수 있습니다.

 

SWR 내부에는 Super Cache가 존재합니다. 이 객체의 key는 useSWR 훅의 첫 번째 인자로 받은 문자열이고, 이 key를 통해 cache를 만들어 메모리에 저장하고, 데이터를 찾습니다.

✨기능

SWR은 다음과 같은 주요 기능을 가집니다.

  1. 빠르고, 가볍게 재사용 가능한 데이터 가져오기.
  2. 내장된 캐시 및 요청 중복 제거
  3. 실시간 업데이트로 유저 경험 향상

✨기본적인 코드

import useSWR from 'swr'

const fetcher = (url) => fetch(url).then(r => r.json()) // fetch 내장 API 사용
 
function Profile() {
  const { data, error, isLoading } = useSWR('/api/user', fetcher)
 
  if (error) return <div>failed to load</div>
  if (isLoading) return <div>loading...</div>
  return <div>hello {data.name}!</div>
}

useSWR 훅의 첫 인자는 Key로 문자열을 받습니다. 이는 고유 식별자로 사용됩니다.

fetcher는 두 번째 인자로, 함수를 받습니다. 이 함수는 Key 문자열을 인자로 받습니다. 이는 비동기 함수가 될 수도 있고 fetch API 혹은 Axios와 같은 라이브러리를 사용할 수 있습니다.

Bound Mutate

Bound Mutate는 현재 사용중인 useSWR 훅을 기반으로 데이터를 변경할 수 있습니다.

import useSWR from 'swr'
 
function Profile () {
  const { data, mutate } = useSWR('/api/user', fetcher)

	const handler = async () => {
    const newName = data.name.toUpperCase()
		mutate({ ...data, name: newName }, false)
    await requestUpdateUsername(newName)
  }

  return (
    <div>
      <h1>My name is {data.name}.</h1>
      <button onClick={handler}>Uppercase my name!</button>
    </div>
  )
}

mutate를 통해 캐시에 존재하는 데이터를 업데이트 할 수 있습니다.

mutate의 두 번째 인자는 revalidate, 재검증 반환 여부를 나타냅니다. 재검증이란 refetch, 새로 데이터를 받아오는 형식으로 생각하시면 됩니다!

mutate({ ...data, name: newName }, false) 
mutate({ ...data, name: newName }, true)

true일 경우, 재검증을 하여 데이터를 API로 부터 요청하게 되고, false일 경우 UI상의 데이터만 변경될 뿐, 데이터를 재 요청하지 않습니다. 유저는 변경된 값을 보게 될 수 있으므로 유저 경험이 더욱 좋아지게 되는 것이죠!

✨Global Mutate

전역에서 상태를 관리하기 위해서는 Redux, Recoil과 같은 상태 관리 라이브러리를 보통 많이 사용합니다. 이와 같은 기능을 SWR에서도 사용할 수 있는데요. SWR의 데이터를 전역에서 사용할 수 있습니다.

Global Mutate는 전역에서 Mutate 할 수 있는 것입니다. 

import { useSWRConfig } from "swr"
 
function App() {
  const { mutate } = useSWRConfig()
  mutate(key, data, options)
}

혹은

import { mutate } from "swr"
 
function App() {
  mutate(key, data, options)
}

형식으로 가져올 수 있습니다!

key 값은 useSWR의 첫 인자로 등록한 URL 문자열을 key값으로 설정합니다.

bound mutate와 기능적으로 동일하나, key값으로 원하는 데이터에 접근할 수 있는 기능을 가지고 있습니다

❗결론!

useSWR을 사용하는 것은, 사용자 경험을 좋게 하면서도 불필요한 refetch를 줄일 수 있다는 생각이 들었습니다. 프론트엔드에서 정말 중요한 개념이라 생각되네요.

다음 시간에는 React-Query에 대해서 공부하고, SWR과의 차이점에 대해서 살펴보겠습니다!