SWR 정리

HyosikPark·2021년 3월 3일
7

Overview

npm i swr


import useSWR from 'swr'

function fetcher(key) {
  ...
	return data
}

function Component() {
	const {data, error, isValidating, mutate} = useSWR(key, fetcher, options)
    
    if (error) return <div>err</div>
    if (!data) return <div>loaidng</div>
    return <div>{data}</div>
}

useSWR의 key가 fetcher로 전달되고 return 값이 data에 담긴다.
fetcher에서 error가 발생할 경우 error가 반환된다.
key는 swr의 식별자로써 서로 다른 컴포넌트에서 불러와도 data를 options의 캐싱을 설정할 경우 서로 data를 공유한다. api 요청일 경우 최초 1회만 요청을 하고 나머지는 캐싱된 값을 사용할 수 있다.

API options

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

params

key : 고유의 식별자
fetcher: Promise data를 반환하는 function
options: 다양한 options 제공

return Values

data: fetcher로부터 반환된 data
error: fetcher에서 error가 발생할 경우 error 반환 기본(undefined)
isValidating: boolean fetching중일 때 true
mutate: caching된 데이터를 업데이트 optimistic UI처럼 사용 가능.

mutate('newData', false)
data 값을 'newData'로 바꾸고 2번째 옵션이 false일 경우 서버로 재요청 x

options

initialData

loading중 일때 초기 data값 설정.

revalidateOnMount

boolean: component가 mount될 때 재 실행 여부

fetcher

fetcher functions

revalidateOnFocus = true

boolean: 다른 tab에 갔다가 다시 focus를 얻을 때 재 실행 여부

revalidateOnReconnect = true

boolean: 브라우저 network가 다시 연결되었을 때 재 실행 여부

refreshInterval = 0

time(ms): polling 주기 설정

refreshWhenHidden = false

time(ms): window에 focus가 없을 때에도 polling 여부

refreshWhenOffline = false

browser가 offline일 때에도 polling 여부

shouldRetryOnError = true

fetcher error 발생 시 재 실행 여부

dedupingInterval = 2000

캐싱 시간

focusThrottleInterval = 5000

최소 재 실행 간격

loadingTimeout = 3000

loading 상태 제한 시간

errorRetryInterval = 5000

error 발생 시 재 실행 간격

errorRetryCount

최대 errorRetry 횟수

onLoadingSlow(key , config)

loading 제한 시간을 넘어설 경우 실행될 callback 함수

onSuccess(data, key, config)

요청이 성공적일 경우 실행될 callback 함수

onError(err, key, config)

error 발생 시 실행될 callback 함수

onErrorRetry(err, key, config, revalidate, revalidateOps)

error retry handler

Global Configuration

SWRConfig component의 child component들에게 사용된 swr에 동일한 options를 부여할 수 있다.

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

Conditional Fetching

Contitional

// conditionally fetch
const { data } = useSWR(shouldFetch ? '/api/data' : null, fetcher)

// ...or return a falsy value
const { data } = useSWR(() => shouldFetch ? '/api/data' : null, fetcher)

// ... or throw an error when user.id is not defined
const { data } = useSWR(() => '/api/data?uid=' + user.id, fetcher)

Arguments

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

셋다 동일

mutiple Arguments

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

위 방법은 사용가능하나 권장되지는 않는다.
token이 달라도 key는 같기 때문에 동일한 key로 보고 data Fetching이 이뤄지지 않는다.

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

배열로 묶어줄 경우 token 변경시에 data가 fetching된다.

// Don’t do this! Deps will be changed on every render.
useSWR(['/api/user', { id }], query)

// Instead, you should only pass “stable” values.
useSWR(['/api/user', id], (url, id) => query(url, { id }))

객체를 사용할 경우 불러올 때마다 매번 새로운 값이 생겨 서로 다른 key로 취급되니 주의

Mutation

Mutate

동일한 key를 가진 전역의 모든 SWR을 revalidation할 수 있다.

import useSWR, { mutate } from 'swr'

function App () {
  return (
    <div>
      <Profile />
      <button onClick={() => {
        // set the cookie as expired
        document.cookie = 'token=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;'

        // tell all SWRs with this key to revalidate
        mutate('/api/user', newData)
      }}>
        Logout
      </button>
    </div>
  )
}

mutate Based on Current Data

현재의 data를 매개변수로 받아서 data를 refetching할 수 있다.

mutate(key, async (currentData) => newData))

bound Mutate

현재의 component에서 반환된 mutate function을 사용하여 refetching하는 방법 첫번째 인자로 key를 사용할 필요가 없다.

import useSWR from 'swr'

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

  return (
    <div>
      <h1>My name is {data.name}.</h1>
      <button onClick={async () => {
        const newName = data.name.toUpperCase()
        // send a request to the API to update the data
        await requestUpdateUsername(newName)
        // update the local data immediately and revalidate (refetch)
        // NOTE: key is not required when using useSWR's mutate as it's pre-bound
        mutate({ ...data, name: newName })
      }}>Uppercase my name!</button>
    </div>
  )
}

Revalidate

data를 다시 refetching할 때 사용

{revalidate} = useSWR(key ,fetcher, options)

revalidate();

triger

전역의 동일한 key를 가진 swr을 다시 refetching

import {triger} from 'swr'

trigger(key, shouldRevalidation: boolean)

useSWRInfinite

pagination에 적합하게 추가된 hook

const { data, error, isValidating, mutate, size, setSize } = useSWRInfinite(
  getKey, fetcher?, options?
)

0개의 댓글