시냅스

React-Query 사용법 본문

ReactJS

React-Query 사용법

ted k 2021. 12. 3. 14:48

Reqct-Query

 

React Query

Hooks for fetching, caching and updating asynchronous data in React

react-query.tanstack.com

 

데이터 무결성을 위해 각각의 request에 key를 부여하여 최신 데이터를 참조할 수 있게 보장한다.

axios의 경우 요청에 실패할 때에 interceptor를 통해 재요청, 새로고침을 해줘야 하는데

React-Query 는 라이브러리에서 자동으로 처리한다.

(window가 다시 포커스 되거나, 네트워크가 다시 연결되거나, 특정 쿼리 인스턴스가 다시 만들어졌을 때 등)

 

npm i react-query
yarn add react-query

 

사용법

 

Setting

 import { QueryClient, QueryClientProvider, useQuery } from 'react-query'
 
 const queryClient = new QueryClient()
 
 export default function App() {
   return (
     <QueryClientProvider client={queryClient}>
       <Example />
     </QueryClientProvider>
   )
 }

QueryClient를 통해 객체를 하나 생성하여 비동기 요청을 한 context를 구분한다.

 

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

내부에서 useQuery를 이용하여 비동기 처리를 할 수 있는데, 이때 반환값은 isLoading, error, data로 각 이름에 맡는 역할을 하게 된다.

 

Key

 // A list of todos
 useQuery('todos', ...) // queryKey === ['todos']
 
 // Something else, whatever!
 useQuery('somethingSpecial', ...) // queryKey === ['somethingSpecial']

useQuery 내부 첫 번째 인자로 들어가는 것이 key 값이 되어 리퀘스트에 대한 구별을 해준다.

키 값은 라이브러리 내부에서는 유일한 값을 가진 배열로 변환된다.

 

 // An individual todo
 useQuery(['todo', 5], ...)
 // queryKey === ['todo', 5]
 
 // An individual todo in a "preview" format
 useQuery(['todo', 5, { preview: true }], ...)
 // queryKey === ['todo', 5, { preview: true }]
 
 // A list of todos that are "done"
 useQuery(['todos', { type: 'done' }], ...)
 // queryKey === ['todos', { type: 'done' }]

또는 삽입할 때 index 값을 갖는 배열을 선언하여 명시적으로 지정해줄 수 있다.

 

Mutations

useQuery를 CUD에 사용하는 것을 권장하지 않고

Mutation을 통해 CUD에 사용되는 사이드이펙트들을 처리한다.

 

 function App() {
   const mutation = useMutation(newTodo => {
     return axios.post('/todos', newTodo)
   })
 
   return (
     <div>
       {mutation.isLoading ? (
         'Adding todo...'
       ) : (
         <>
           {mutation.isError ? (
             <div>An error occurred: {mutation.error.message}</div>
           ) : null}
 
           {mutation.isSuccess ? <div>Todo added!</div> : null}
 
           <button
             onClick={() => {
               mutation.mutate({ id: new Date(), title: 'Do Laundry' })
             }}
           >
             Create Todo
           </button>
         </>
       )}
     </div>
   )
 }

위와 같은 방식으로 처리할 수 있다.

 

useMutation(addTodo, {
   onMutate: variables => {
     // 시작!
 
     // Optionally return a context containing data to use when for example rolling back
     return { id: 1 }
   },
   onError: (error, variables, context) => {
     // 에러 시
     console.log(`rolling back optimistic update with id ${context.id}`)
   },
   onSuccess: (data, variables, context) => {
     // 성공 시!
   },
   onSettled: (data, error, variables, context) => {
     // 성공이거나 에러나 상관 없이
   },
 })

위와 같이 라이프사이클 인터셉트에 따라 분기할 수도 있다!

 

 

 

Comments