본문 바로가기
챌린지/패스트캠퍼스 공부 루틴 챌린지

패스트캠퍼스 챌린지 17일차 (SWR)

by 무벅 2022. 2. 9.
반응형

22.2.9 (수) +17days

SWR

stale-while-revalidate(HTTP 캐시 전략중 하나)

의도적으로 cache된 date를 return 하고 fetch(revalidate)한 후 data를 update 한다.

SWR을 사용하면 컴포넌트는 지속적이며 자동으로 데이터 업데이트 스트림을 받게 됩니다.그리고 UI는 항상 빠르고 반응적 입니다.

개요

import useSWR from 'swr'

function Profile() {
  const { data, error } = useSWR('/api/user', fetcher)

  if (error) return <div>failed to load</div>
  if (!data) return <div>loading...</div>
  return <div>hello {data.name}!</div>
}

이 예시에서, useSWR hook은 key 문자열과 fetcher 함수를 받습니다. key는 데이터의 고유한 식별자이며(일반적으로 API URL) fetcher로 전달될 것입니다. fetcher는 데이터를 반환하는 어떠한 비동기 함수도 될 수 있습니다. 네이티브 fetch 또는 Axios와 같은 도구를 사용할 수 있습니다.

hook은 두 개의 값을 반환합니다: 요청의 상태에 기반한 data와 error.

기능

단 한 줄의 코드로 프로젝트 내의 데이터 가져오기 로직을 단순화할 수 있으며, 다음과 같은 모든 놀라운 기능들을 바로 사용할 수도 있습니다.

  • 빠르고가볍고재사용 가능한 데이터 가져오기
  • 내장된 캐시 및 요청 중복 제거
  • 실시간 경험
  • 전송 및 프로토콜에 구애받지 않음
  • SSR / ISR / SSG support
  • TypeScript 준비
  • React Native

시작하기

설치

yarn add swr
npm install swr

빠른 시작

JSON 데이터를 사용하는 일반적인 RESTful API라면 먼저 네이티브 fetch의 단순한 래퍼인 fetcher 함수를 생성해야 합니다.

const fetcher = (...args) => fetch(...args).then(res => res.json())

그 다음, useSWR을 임포트하고 함수 컴포넌트 내에서 사용하여 시작하면 됩니다.

import useSWR from 'swr'

function Profile () {
  const { data, error } = useSWR('/api/user/123', fetcher)

  if (error) return <div>failed to load</div>
  if (!data) return <div>loading...</div>

  // 데이터 렌더링
  return <div>hello {data.name}!</div>
}

일반적으로, 세 가지 요청 상태가 가능합니다: "loading", "ready", "erorr". data와 error 값을 사용해 현재 요청의 상태를 알아내고, 해당하는 UI를 반환할 수 있습니다.

재사용 가능하게 만들기

웹 앱을 구축할 때, UI의 많은 곳에서 데이터를 재사용할 필요가 있을 것입니다. SWR 위에서는 재사용 가능한 데이터 hook을 만드는 것이 믿을 수 없을 정도로 쉽습니다.

function useUser (id) {
  const { data, error } = useSWR(`/api/user/${id}`, fetcher)

  return {
    user: data,
    isLoading: !error && !data,
    isError: error
  }
}

데이터는 이제 데이터가 필요한 컴포넌트로 범위가 제한되었으며 모든 컴포넌트는 서로에게 독립적입니다. 모든 부모 컴포넌트들은 데이터나 데이터 전달에 관련된 것들을 알 필요가 없습니다. 그냥 렌더링할 뿐입니다. 코드는 이제 유지하기에 더 간단하고 쉽습니다.

가장 아름다운 것은 이들이 동일한 SWR 키를 사용하며 그 요청이 자동으로 중복 제거캐시공유되므로, 단 한 번의 요청만 API로 전송된다는 것입니다.

또한, 애플리케이션은 이제 사용자 포커스나 네트워크 재연결 시에 데이터를 갱신할 수 있습니다! 이는 사용자의 노트북이 슬립으로부터 깨어나거나 브라우저 탭을 전환할 때 자동으로 데이터가 갱신된다는 것을 의미합니다.

자동 갱신

https://swr.vercel.app/ko/docs/revalidation

 

자동 갱신 – SWR

💡 수동으로 데이터를 갱신하려면 뮤테이션을 확인하세요. 페이지에 다시 포커스하거나 탭을 전환할 때, SWR은 자동으로 데이터를 갱신합니다. 최신 상태로 즉시 동기화할 수 있어 유용합니다.

swr.vercel.app

포커스 / 인터벌 / 재연결 시에 자동으로 갱신할 수 있고 자동 갱신을 비활성화 할 수 있습니다.

리소스가 불변할 경우, 다시 갱신해도 변경되지 않습니다. 이런 경우를 대비해 모든 종류의 자동 갱신을 비활성화 할 수 있습니다.

import useSWRImmutable from 'swr/immutable'

// ...
useSWRImmutable(key, fetcher, options)

일반적인 useSWR hook과 동일한 API 인터페이스를 갖고 있습니다. 갱신 옵션을 다음과 같이 비활성화하여 동일한 작업을 수행할 수도 있습니다.

useSWR(key, fetcher, {
  revalidateIfStale: false,
  revalidateOnFocus: false,
  revalidateOnReconnect: false
})

// 다음과 동일
useSWRImmutable(key, fetcher)

revalidateIfStale은 마운트 시에 스태일 데이터가 존재할 경우 SWR이 갱신해야 할지 여부를 제어합니다.

위의 두 개의 hook은 완전히 동일한 작업을 수행합니다. 데이터가 캐시 되기만 하면 절대 다시 요청하지 않습니다.

API 옵션

const { data, error, isValidating, mutate } = useSWR(key, fetcher, options)

전역 설정

SWRconfig 컨텍스트는 모든 SWR hook에 대한 전역 설정(options)을 제공합니다.

<SWRConfig value={options}>
  <Component/>
</SWRConfig>

이 예시에서, 모든 SWR hook은 제공된 동일한 fetcher를 사용해 JSON 데이터를 로드하고 기본적으로 3초마다 갱신합니다.

import useSWR, { SWRConfig } from 'swr'

function Dashboard () {
  const { data: events } = useSWR('/api/events')
  const { data: projects } = useSWR('/api/projects')
  const { data: user } = useSWR('/api/user', { refreshInterval: 0 }) // 오버라이드

  // ...
}

function App () {
  return (
    <SWRConfig 
      value={{
        refreshInterval: 3000,
        fetcher: (resource, init) => fetch(resource, init).then(res => res.json())
      }}
    >
      <Dashboard />
    </SWRConfig>
  )
}

추가 APIs

캐시 공급자

나열된 모든 옵션 외에도, SWRConfig는 선택적으로 provider 함수도 받습니다. 더 자세한 내용은 캐시 섹션을 참고해 주세요.

<SWRConfig value={{ provider: () => new Map() }}>
  <Dashboard />
</SWRConfig>

전역 설정에 접근하기

useSWRConfig hook을 사용해 전역 설정과 mutate 및 cache를 얻을 수 있습니다.

import { useSWRConfig } from 'swr'

function Component () {
  const { refreshInterval, mutate, cache, ...restConfig } = useSWRConfig()

  // ...
}

데이터 가져오기

https://swr.vercel.app/ko/docs/data-fetching

const { data, error } = useSWR(key, fetcher)

이것은 SWR의 아주 핵심적인 API입니다. 여기의 fetcher는 SWR의 key를 받고 데이터를 반환하는 비동기 함수입니다.

반환된 값은 data로 전달되며, 만약 throws라면 error로 잡힙니다.

fetcher가 전역으로 제공된다면 파라미터에서 생략할 수 있습니다.

가져오기

데이터 가져오기를 다루는 어떠한 라이브러리든 사용할 수 있습니다.

에러 처리

fetcher 안에서 에러가 발생했다면 hook에 의해 error로 반환됩니다.

const fetcher = url => fetch(url).then(r => r.json())

// ...
const { data, error } = useSWR('/api/user', fetcher)

fetch 프로미스가 거부되면 error 객체가 정의됩니다.

에러 재시도

SWR은 지수 백오프 알고리즘를 사용해 에러 시 요청을 재시도합니다. 이 알고리즘을 사용하면 에러로부터 앱을 빠르게 복구할 수 있으며 너무 자주 재시도하여 리소스를 낭비하지도 않습니다.

자동 갱신

https://swr.vercel.app/ko/docs/revalidation

조건부 가져오기

조건부

null을 사용하거나 함수를 key로 전달하여 데이터를 조건부로 가져옵니다. 함수가 falsy 값을 던지거나 반환하면 SWR은 요청을 시작하지 않습니다.

// 조건부 가져오기
const { data } = useSWR(shouldFetch ? '/api/data' : null, fetcher)

// ...또는 falsy 값 반환
const { data } = useSWR(() => shouldFetch ? '/api/data' : null, fetcher)

// ...또는 user.id가 정의되지 않았을 때 에러 throw
const { data } = useSWR(() => '/api/data?uid=' + user.id, fetcher)

의존

SWR은 다른 데이터에 의존하는 데이터를 가져오는 것 또한 허용합니다. 이는 다음 데이터 가져오기를 위한 동적 데이터 조각이 필요할 때, 직렬 가져오기뿐만 아니라 가능한 최대 병렬 처리(폭포수 방지)를 보장합니다.

function MyProjects () {
  const { data: user } = useSWR('/api/user')
  const { data: projects } = useSWR(() => '/api/projects?uid=' + user.id)
  // 함수를 전달할 때, SWR은 반환 값을 `key`로 사용합니다.
  // 함수가 falsy를 던지거나 반환한다면,
  // SWR은 일부 의존성이 준비되지 않은 것을 알게 됩니다.
  // 이 예시의 경우 `user.id`는 `user`가 로드되지 않았을 때
  // 에러를 던집니다.

  if (!projects) return 'loading...'
  return 'You have ' + projects.length + ' projects'
}

인자

기본값으로, key는 인자로써 fetcher에 전달됩니다. 따라서 다음 세 가지 표현식은 동일합니다.

useSWR('/api/user', () => fetcher('/api/user'))
useSWR('/api/user', url => fetcher(url))
useSWR('/api/user', fetcher)

다중 인자

어떤 시나리오에서는 fetcher 함수에 여러 인자(어떠한 값이나 객체도 가능)를 전달하는 것이 유용합니다. 인증된 가져오기 요청 예시입니다:

useSWR('/api/user', url => fetchWithToken(url, token))

이는 올바르지 않습니다. 왜냐하면 데이터의 식별자(또한 캐시 키)가 '/api/user'이고, 만약 token이 변경되어도 SWR은 여전히 동일한 키를 사용하기 때문에 잘못된 데이터를 반환합니다.

대신에 fetcher의 다중 인자를 포함하는 배열을 key 파라미터로 사용할 수 있습니다.

const { data: user } = useSWR(['/api/user', token], fetchWithToken)

fetchWithToken 함수는 여전히 동일한 두 개의 인자를 받지만, 캐시 키는 이제 token과 연결되었습니다.

뮤테이션

https://swr.vercel.app/ko/docs/mutation

 

뮤테이션 – SWR

뮤테이션 useSWRConfig() hook으로부터 mutate 함수를 얻을 수 있으며, mutate(key)를 호출하여 동일한 키를 사용하는 다른 SWR hook*에게 갱신 메시지를 전역으로 브로드캐스팅할 수 있습니다. 이 예시는 유

swr.vercel.app

페이지네이션

https://swr.vercel.app/ko/docs/pagination

 

페이지네이션 – SWR

✅ 이 API를 사용하려면 최신 버전(≥ 0.3.0)으로 업데이트해 주세요. 이전의 useSWRPages API는 이제 사용되지 않습니다. SWR은 페이지네이션과 인피니트 로딩과 같은 일반적인 UI 패턴을 지원하는 전용

swr.vercel.app

프리패칭

https://swr.vercel.app/ko/docs/prefetching

 

프리패칭 데이터 – SWR

프리패칭 데이터 SWR을 위한 데이터 프리패칭 방법은 다양합니다. 최상위 요청에 대해서는 rel="preload"를 적극적으로 권장합니다. HTML 안에 넣기만 하면 됩니다. 쉽고 빠르며 네이티브입니다. 심지

swr.vercel.app

Next.js와 함께 사용하는 방법

https://swr.vercel.app/ko/docs/with-nextjs

 

Next.js와 함께 사용하는 방법 – SWR

페이지가 빈번하게 업데이트하는 데이터를 포함하고 이를 프리렌더링할 필요가 없다면, SWR은 완벽하게 적합하며 어떠한 특별한 설정도 필요하지 않습니다. useSWR을 임포트하고 데이터를 사용하

swr.vercel.app

성능

https://swr.vercel.app/ko/docs/advanced/performance

 

성능 – SWR

성능 SWR은 모든 종류의 웹 앱에서 중요한 기능들을 제공하므로 성능을 가장 중요시합니다. SWR의 내장 캐싱과 중복 제거 기능은 불필요한 네트워크 요청을 생략하지만, useSWR hook 자체의 성능은

swr.vercel.app

SWR은 모든 종류의 웹 앱에서 중요한 기능들을 제공하므로 성능을 가장 중요시합니다.

SWR의 내장 캐싱 중복 제거 기능은 불필요한 네트워크 요청을 생략하지만, useSWR hook 자체의 성능은 여전히 중요합니다. 복잡한 앱에서는 단일 페이지 렌더링에 useSWR이 수백 번 호출될 수 있습니다.

SWR은 앱에서 다음을 보장합니다:

  • 불필요한 요청 없음
  • 불필요한 리렌더링 없음
  • 불필요한 코드 임포트 없음

어떠한 코드 수정도 필요 없습니다.

 

SWR 은,

키가 같다면 요청이 자동으로 중복 제거, 캐시, 공유 된다.

여러 컴포넌트에서 SWR을 사용해도 키를 가지고 자동으로 컨트롤 한다ㅌ.

사용자 포커스나 네트워크 재연결시 갱신된다.

 

정리

SWR ⇒ Stale-While-Revalidate

키 ⇒ 중복 제거 / 캐시 / 공유

Revalidate ⇒ 다양한 옵션 (포커스 / 네트워크 / interval)

전역 설정 ⇒ SWRConfig / persistant cache

뮤테이션 ⇒ 데이터를 업데이트

페이지네이션 ⇒ useSWRInfinite

프리패칭 ⇒ <head> / mutate / 데이터 프리필

성능 ⇒ 중복제거 / depugingInterval / 비교

 

 

 

 

 

22.2.9 +17days

 

 

 

 

 

https://bit.ly/37BpXiC

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다

 

 

 

 

 

 

반응형

댓글