React-query 시작하기

·2022년 9월 11일
0
post-thumbnail

React-query 왜 쓰는 건가?

redux 를 예시로 들어봅시다. redux 의 경우 비동기 처리는 middleware를 사용합니다. 어떠한 프로젝트에서 어떠한 비동기 모듈을 쓰냐에 따라 세팅도 천차만별이고, reducer 에 작업해주어야 할 것도 많죠.

보통은 그래서 extra-reducer 에 작업하는 걸로 알고 있습니다.

중요한 부분은, redux 의 상태 값만 봐서는, 어떤게 비동기 데이터이고, 어떤게 클라이언트에서 얻은 데이터인지 알 수 없다는 것 입니다. 뭐 개발자마다 어떻게 어떻게 분류한다고 하더라도, 설계 생각하랴, 다시 또 slice 만들랴, 시간 소모한다면 저는 그냥 구분 못한 체 쓸 거 같습니다.

여튼 react-query 를 쓰면, 우선 전역 state 가운데, client-stateserver-state 를 분류하는 것이 가능해집니다. client-state 는 상태관리 라이브러리를 통해 관리하고, server-statereact-query 로 제어하면 되기 때문입니다. key 값을 통한 캐싱이 가능하기 때문에, 요청 수도 줄어들 것입니다. 일일히 pending 일때, fulfill 일때, error 일때 나눌 필요도 없고, 거기에 클라이언트 단에서 자주 쓰이는 유용한 기능도 있다고 하니, 안 쓸 이유가 없는 거죠.

React-query 시작하기

queryClient

처음 비동기 요청을 통해 데이터를 받는 경우, key 값과 함께 맵핑되어, 캐시에 저장됩니다. 이윽고, 다시 페이지에 돌아오는 경우, 다시금 비동기 요청을 하게 되는데, 이때 이미 캐싱 되어 있는 데이터의 경우 요청을 하지 않은 체 캐시에서 해당 반환값을 그대로 리턴하게 합니다. queryClientreact-query 에서 이러한 과정이 이루어지도록 호출하는 함수입니다.

import React from "react";
import TodoInput from "./components/TodoInput";
import { RecoilRoot } from "recoil";
import { QueryClient, QueryClientProvider } from "react-query";
import TodoList from "./components/TodoList";

const queryClient = new QueryClient();

function App() {
  return (
    <RecoilRoot>
      <QueryClientProvider client={queryClient}>
        <TodoInput />
        <TodoList />
      </QueryClientProvider>
    </RecoilRoot>
  );
}

export default App;

useQuery

쿼리는 고유 key 값을 통해 처음 요청을 하거나, 캐싱된 값을 읽어옵니다.

function Todos() {
   const { isLoading, isError, data, error } = useQuery('todos', fetchTodoList)
 
   if (isLoading) {
     return <span>Loading...</span>
   }
 
   if (isError) {
     return <span>Error: {error.message}</span>
   }
 
   // We can assume by this point that `isSuccess === true`
   return (
     <ul>
       {data.map(todo => (
         <li key={todo.id}>{todo.title}</li>
       ))}
     </ul>
   )
 }

QueryKey

useQuery() 의 첫번째 매개변수에 들어가는 항목으로, 일반적으로 쿼리의 고유 key 는 string 값을 암호화 한 값으로 저장되게 됩니다. 단순 문자열로 저장하여도 좋고, 복잡한 배열을 통해서도 key을 설정하는 것이 가능합니다. 예를 들어, 유사한 카테고리의 비동기의 경우라면, ["카테고리", id] 이런 형태로 저장하는 방법이 유용할 겁니다.

// An individual todo
 useQuery(['todo', 5], ...)
 // queryKey === ['todo', 5]
 
 // And 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' }]

QueryFN

useQuery() 의 두번째 매개변수에 들어가는 항목으로, 비동기 요청을 통해, 반환되는 Promise 데이터가 되겠습니다. PromiseData 가 나오거나, Error 가 나올 수 있습니다.

profile
새로운 것에 관심이 많고, 프로젝트 설계 및 최적화를 좋아합니다.

0개의 댓글