React: SWR ?

김대은·2022년 7월 28일
0

리액트에서 전역 상태관리를 하기 위해 Redux라는 라이브러리를 사용하는데,
코드의 양도 많고 불편함점이 의외로 많다.

그중 제로초님의 강의를 보다가 알게된 SWR

SWR에대해 알아보려 한다.

일단 리덕스의 불편한점

  • 리덕스 흐름에 따라( View -> Dispatch -> Action -> Reducer -> Store -> State)작성해야해서
    코드양이 많음...

  • 한번 가져왔던 정보라도 컴포넌트가 마운트 될 때마다 새로 가져와서 갈아 끼워야함

  • 지속적으로 리덕스 로컬 스토어의 상태를 서버 상태와 맞추기 위해 추가적으로 동기화 작업을 해줘야함

SWR ?

공식 홈페이지에 가보면 React-hooks Library for Data fetching 이라는 소개를 볼 수 있다.
말 그대로 리액트 훅을 사용할때 데이터를 가져오기 위한 라이브러리 라는 것이다.

SWR은 자동적으로 지속적이게 요청을 보내지만, 데이터를 받는것이 요청이후 응답을 토대로 받는 구조가 아니다.

먼저 저장된 캐시에서 데이터를 보내주고, SWR은 내부적으로 검증을 하는 과정을 거치게 된다.
따라서 우리가 보기에 반응속도가 더 빠르다는 장점이 있다.

사용법

Json 데이터를 사용하는 일반적인 RESTful API라면 먼저 fetcher 함수를 생성한다.

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

그다음,

   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>
   }

SWR 공식 홈페이지에 나와있는 방법이다.
일반적으로, 세 가지 요청 상태가 가능합니다: "loading", "ready", "error". 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
    }
  }

그리고 컴포넌트에서 사용합니다.

  function Avatar ({ id }) {
    const { user, isLoading, isError } = useUser(id)

    if (isLoading) return <Spinner />
    if (isError) return <Error />
    return <img src={user.avatar} />
  }

옵션

const { data, error, isValidating, mutate } = useSWR(key, fetcher, options)
  1. 파라미터
  • key : 요청을 위한 고유한 키 문자열
  • fetcher : 데이터를 가져오기 위한 함수를 반환하는 Promise
  • options : SWR hook 을 위한 옵션 객체
  1. 반환 값
  • data : fetcher 가 실행 된 후 주어진 키에대한 데이터 (로드되지않앗으면 undefined)
  • error : fetcher 가 던진 에러
  • isValidating : 요청이나 갱신 로딩의 여부
  • mutate : 캐시된 데이터를 뮤테이트 하기 위한 함수
  1. 옵션들
    https://swr.vercel.app/ko/docs/options
    워낙 공식 사이트에 너무 잘 나와있어서...
    궁금했던 mutate에대해서만 알아보고 가려 한다.

mutation

갱신하기

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

  import useSWR, { useSWRConfig } from 'swr'

  function App () {
    const { mutate } = useSWRConfig()

    return (
      <div>
        <Profile />
        <button onClick={() => {
          // 쿠키를 만료된 것으로 설정
          document.cookie = 'token=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;'

          // 이 키로 모든 SWR에게 갱신하도록 요청
          mutate('/api/user')
        }}>
          Logout
        </button>
      </div>
    )
  }

이 예시는 유저가 “로그아웃” 버튼을 클릭할 때 로그인 정보를 자동으로 갱신하는 방법을 보여줍니다.

뮤테이션과 POST 요청

데이터에 로컬 뮤테이션을 적용하면, 변경사항을 더 빠르게 느낄 수 있다.
mutate를 사용하면 갱신하고 최종적으로 최신 데이터로 이를 대체하는 동안에
로컬 데이터를 프로그래밍 방식으로 업데이트할 수 있습니다.

  import useSWR, { useSWRConfig } from 'swr'

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

    return (
      <div>
        <h1>My name is {data.name}.</h1>
        <button onClick={async () => {
          const newName = data.name.toUpperCase()

          // 로컬 데이터를 즉시 업데이트하지만, 갱신은 비활성화
          mutate('/api/user', { ...data, name: newName }, false)

          // 소스 업데이트를 위해 API로 요청 전송
          await requestUpdateUsername(newName)

          // 로컬 데이터가 올바른지 확인하기 위해 갱신(refetch) 트리거
          mutate('/api/user')
        }}>Uppercase my name!</button>
      </div>
    )
  }

자세한건 공식사이트를 보자 너무너무 잘 나와있다.

profile
매일 1% 이상 씩 성장하기

0개의 댓글