React Query(1) 살펴보기

GUK·2023년 12월 12일
0

Library

목록 보기
1/2
post-thumbnail

들어가며

React Query는 React의 누락된 데이터를 가져오는 라이브러리로 설명되지만, 보다 전문적인 용어로는 React 응용프로그램의 서버 상태를 불러오기, 캐싱, 동기화 및 업데이트하는 것을 쉽게 해줍니다.
출처 tanstack 공식문서


쉽게 말하면 React Query는 서버 데이터를 보다 쉽게 처리해주는 라이브러리 입니다.


React Query의 주요 기능?

  1. 데이터 패칭 :
  • API에서 데이터를 가져오는 작업을 간단하게 만들어줍니다.

  1. 데이터 캐싱 :
  • 한 번 가져온 데이터를 캐시에 저장하여, 동일한 요청이 다시 발생할 때 빠르게 응답할 수 있습니다.

  1. 배경 업데이트 :
  • 데이터가 변경될 가능성이 있는 경우, 사용자가 알아차리지 못하는 사이에 데이터를 자동으로 업데이트합니다.

  1. 데이터 동기화 :
  • 여러 컴포넌트에서 동일한 데이터를 사용할 경우, 하나의 컴포넌트에서 데이터가 변경되면 다른 컴포넌트의 데이터도 동기화합니다.

  1. 에러 처리 :
  • 데이터 패칭 과정에서 에러가 발생하면 이를 감지하고 적절히 처리할 수 있습니다.

따라서 React Query는 서버 데이터를 다루는 복잡한 작업을 대신 처리해주어, 개발자가 이에 대해 신경 쓰지 않아도 되기 떄문에 이로 인해 서버 데이터를 다루는 코드가 간결해지고, 애플리케이션의 성능과 사용자 경험을 향상 시킬 수 있습니다.

React Query 사용해보기


React에서 react query를 사용하려면 QueryClientProvider 필수

QueryClientProvider는 최상위 폴더에서 사용하며 자식 컴포넌트들을 감싸줘야 합니다.

import { QueryClient, QueryClientProvider } from "react-query";

const queryClient = new QueryClient();

function App() {
  return;
  <QueryClientProvider client={queryClient}>...</QueryClientProvider>;
}

React Query의 3가지 컨셉

  • Queries
  • Mutations
  • Query Invalidation

1. Queries :

보통 GET으로 받아올 대부분의 API에 사용(데이터 Fetching 용)

  • Queries는 고유 키에 연결된 비동기 데이터에 대한 선언적 종속성 입니다.
  • Queries는 서버에서 데이터를 가져오는 모든 Promise(비동기 처리) 기반 메서드(GET 및 POST 메서드 포함)와 함께 사용할 수 있습니다.
  • 서버의 데이터를 수정하는 메서드를 사용한다면, Mutation을 사용하는 것을 권장합니다.

예제)

import { useQuery } from "react-query";

function App() {
  const info = useQuery("todos", fetchTodoList);
}

// 'todos', Query Key
// fetchTodoList, Query Function

Query Key
Key, Value 맵핑 구조?

  • React Query는 Query Key에 따라 query caching을 관리합니다.

String 형태

// a list of todos
useQuery('todos', ...) // queryKey === ['todos']

// Something else, whatever
useQuery('somethingSpecial', ...); // queryKey === ['somethingSpecial']

Array 형태

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

Query Function
Data Fetching 할 때 Promise 함수를 만드는데,

  • Promise를 반환하는 함수 -> 데이터를 resolve하거나 error를 throw
useQuery("fetchNumber", () => fetchNumber(number), options);



useQuery가 반환하는게 뭔데?

useQuery

const {
  data,
  dataUpdatedAt,
  error,
  errorUpdatedAt,
  failureCount,
  isError,
  isFetched,
  isFetchedAfterMount,
  isFetching,
  isIdle,
  isLoading,
  isLoadingError,
  isPlaceholderData,
  isPreviousData,
  isRefetchError,
  isRefetching,
  isStale,
  isSuccess,
  refetch,
  remove,
  status
} = useQuery(queryKey, queryFn?, {...})
  • data : 마지막으로 성공한 resolve된 데이터(response)
  • error : 에러가 발생했을 때 반환되는 객체
  • isFetching : Request가 in-flight 중일 때 true
  • status, isLoading, isSuccess 등등 : 현재 query의 상태
  • refetch : 해당 query refetch하는 함수 제공
  • remove : 해당 query cache에서 지우는 함수 제공

useQuery Option

} = useQuery(queryKey, queryFn?, {
  cacheTime,
  enabled,
  initialData,
  initialDataUpdatedAt,
  isDataEqual,
  keepPreviousData,
  meta,
  notifyOnChangeProps,
  notifyOnChangePropsExclusions,
  onError,
  onSettled,
  onSuccess,
  placeholderData,
  queryKeyHashFn,
  refetchInterval,
  refetchIntervalInBackground,
  refetchOnMount,
  refetchOnReconnect,
  refetchOnWindowFocus,
  retry,
  retryOnMount,
  retryDelay,
  select,
  staleTime,
  structuralSharing,
  suspense,
  useErrorBoundary,
})
  • onSuccess, onError, onSettled : query fetching 성공/실패/완료 시 실행할 Side Effect 정의
  • enabled : 자동으로 query를 실행 시킬지 말지 여부
  • retry : query 동작 실패 시, 자동으로 retry 할지 결정
  • select : 성공 시 가져온 data를 가공해서 전달
  • keepPreviousData : 새롭게 fetching 시 이전 데이터 유지 여부
  • refetchInterval : 주기적으로 refetch 할지 결정하는 옵션



Mutations

데이터 updating 시 사용

일반적으로 mutation은 queries와 달리 데이터를 생성/업데이트/삭제를 하거나 서버 부작용을 수행하는 데 사용됩니다. 이를 위해 React Query는 useMutation hook을 export 합니다.
tanstack 공식문서

즉, Mutations는 데이터 생성/수정/삭제용 입니다.

예제)

const mutation = useMutation((newTodo) => {
  return axios.post("/todos", newTodo);
});
  • useQuery 보다 더 심플하게 Promise 반환 함수만 있어도 됩니다.
    (단, queryKey를 넣어준다면 devtools에서 볼 수 있음)

useMutation

const {
  data,
  error,
  isError,
  isIdle,
  isLoading,
  isPaused,
  isSuccess,
  mutate,
  mutateAsync,
  reset,
  status,
} = useMutation(mutationFn, {...})
  • mutate : mutation을 실행하는 함수
  • mutateAsync : mutate와 비슷하지만 Promise 반환
  • reset : mutation 내부 상태 clean
  • 나머지는 useQuery와 비슷합니다.

useMutation Option

} = useMutation(mutationFn, {
  mutationKey,
  onError,
  onMutate,
  onSettled,
  onSuccess,
  retry,
  retryDelay,
  useErrorBoundary,
  meta,
})
  • onMutate : 본격적인 Mutation 동작 전에 먼저 동작하는 함수, Optimistic update(낙관적 업데이트) 적용할 때 유용
  • 나머지는 useQuery와 비슷합니다.

낙관적 업데이트란?
서버로부터 성공적으로 업데이트가 되기 전 UI를 업데이트할 수 있도록 해주는 것이다.
즉, 서버로 요청을 보내기 전 UI 업데이트를 진행하는 것이 낙관적 업데이트 !



Query Invalidation

  • queryClient를 통해 invalidate 메소드를 호출하면 끝.
// Invalidate every query in the cache
queryClient.invalidateQueries();
// Invalidate every query with a key that starts with 'todos'
queryClient.invalidateQueries("todos");
  • 이러면 해당 Key를 가진 query는 stale(신선하지 않은) 취급되고, 현재 rendering 되고 있는 query들은 백그라운드에서 refetch 됩니다.

참고: 우아한테크 youtube

profile
Hello, World !

0개의 댓글