[React] swr과 React-Query

youngseo·2022년 7월 31일
0

REACT

목록 보기
28/52
post-thumbnail

swr과 React-Query

비동기로직을 쉽게 다루게 해주는 라이브러리입니다. 이 두가지 기술은 비교적 최근에 나온 라이브러리로 최근에는 해당 라이브러리로 교체하는 편입니다.

그런데 단순히 비동기로직을 쉽게 다루기 위한 라이브러리라기 보다는 어플리케이션에서 상태를 어떻게 관리할 것인지에 대한 측면도 고려해 선택을 하곤 합니다.

SWR

yarn add swr
import useSWR from 'swr' //1. import해서 가져옵니다

export default function ReactPage(){
  
  function fetcher(){ //2. fetcher 함수를 만들어줍니다.
    
  }
  
    const {data, error} = useSWR('key', fetcher)  //3. 첫번쨍 인자로는 유니크한 key를 두번째 인자로는 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>

  // render data
  return <div>hello {data.name}!</div>
}
  • useFetch의 경우 useFetch안에서 useEffect가 컴포넌트가 마운트가 된 직후에 api를 딱 한번 호출하고 그 호출결과를 반환해주었습니다.
  • swr은 내부적으로 sueEffect가 포함되어 있지 않습니다. 즉, 컴포넌트가 마운트된 직후에 딱 1번만 호출하는 것이 아닙니다.
  • 그렇다면 위 코드는 Profile컴포넌트가 렌더링될 때마다 api가 호출되는 것은 아닌지 의문일 수 있습니다. 그런데 그렇지 않습니다. useSRW의 기본적인 컨셉자체가 '/api/user/123'가 유니크한 key값을 만들어준다면 캐싱이 될 수 있도록 설정되어 있습니다.
  • 반환 상태는 loaiding ready error가 있습니다.

재사용가능한 방법

useSWR을 우리만의 커스텀 훅으로 만들 수 있습니다.

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

실습

$ yarn add swr
import useSWR from 'swr' //1. import해서 가져옵니다

export default function ReactPage(){
  
  function fetcher(){ //2. fetcher 함수를 만들어줍니다.
    const { data } = await axios({
      url: "https://jsonplaceholder.typicode.com/posts",
      methods: "GET",
    });
    return data    
  }
  
   const {data: docs, error} = useSWR(`posts`, fetcher)//3. 첫번쨍 인자로는 api를 두번째 인자로는 fetcher을 넘깁니다. //4. 호출 결과로 data와 error를 가져옵니다.
   
  if(error) return <div>failed to load</div>
  if(!docs) return <div>loading..</div>
  
  return (...)
}

+PLUS 공용적인 get함수 만들기

fetcher 함수에 api를 넘겨주고 그 api를 호출하는 경우 url값을 변화하며 사용할 수 있는 공용적인 get fetcher함수를 만들 수 있습니다.

  async function fetcher(url) {
    const { data } = await axios.get(url)
    return data;
  }

  const { data: docs, error } = useSWR("posts", ()=>fetcher('https://jsonplaceholder.typicode.com/posts'));

React Query 공식문서

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

const queryClient = new QueryClient()

export default function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <Example />
    </QueryClientProvider>
  )
}

function Example() {
  const { isLoading, error, data } = useQuery(['repoData'], () =>
    fetch('https://api.github.com/repos/tannerlinsley/react-query').then(res =>
      res.json()
    )
  )

  if (isLoading) return 'Loading...'

  if (error) return 'An error has occurred: ' + error.message

  return (
    <div>
      <h1>{data.name}</h1>
      <p>{data.description}</p>
      <strong>👀 {data.subscribers_count}</strong>{' '}
      <strong>{data.stargazers_count}</strong>{' '}
      <strong>🍴 {data.forks_count}</strong>
    </div>
  )
}

0개의 댓글