본문 바로가기
JavaScript/React

[React] React query 사용해 보기

by junvely 2023. 5. 2.

React query

리액트에서 상태 관리 라이브러리 중 하나로, 강력한 비동기 상태 관리를 지원한다.

리액트 쿼리의 기능은 다음과 같다. 

Backend agnostic: 백엔드에 종속되지 않음
Dedicated Devtools: 전용 개발 도구
Auto Caching: 자동 캐싱
Auto Refetching: 자동 재요청
Window Focus Refetching: 창 포커스 시 자동 재요청
Polling/Realtime Queries: 폴링/실시간 쿼리
Parallel Queries: 병렬 쿼리
Dependent Queries: 의존성 있는 쿼리
Mutations API: 뮤테이션
APIAutomatic Garbage Collection: 자동 쓰레기 수집
Paginated/Cursor Queries: 페이지네이션/커서 쿼리
Load-More/Infinite Scroll Queries: 더 보기/무한 스크롤 쿼리
Scroll Recovery: 스크롤 복원
Request Cancellation: 요청 취소
Suspense Ready!: 서스펜스 준비 완료!
Render-as-you-fetch: 요청하는 동안 렌더링
Prefetching: 사전 로드
Variable-length Parallel Queries: 가변 길이 병렬 쿼리
Offline Support: 오프라인 지원
SSR Support: 서버 사이드 렌더링 지원
Data Selectors: 데이터 셀렉터  
- 공식문서

 

React query 사용방법

1. 설치

yarn add react-query

 

2. App에서 <QueryClientPrivider> 주입

import React from "react";
import Router from "./shared/Router";
**import { QueryClient, QueryClientProvider } from "react-query";**

**const queryClient = new QueryClient();**

const App = () => {

  return (
    **<QueryClientProvider client={queryClient}>**
      <Router />;
    **</QueryClientProvider>**
  );
};

export default App;

 

3. useQuery = Get, 데이터 가져오기

 const { isLoading, isError, data } = useQuery("todos", getTodos);

useQuery hook은 컴포넌트가 마운트될 때 자동으로 해당 함수를 실행하여 데이터를 가져오고, 그 결과를 캐싱한다. 이후에 같은 쿼리를 다시 호출할 때는 캐시된 데이터를 반환하므로 네트워크 요청을 줄이고 애플리케이션의 성능을 향상시킨다.

두번째 비동기 함수 getTodos는 비동기 통신으로 프로미스를 리턴한다. 따라서 반드시 resolve 또는 reject를 리턴하고 에러시 반드시! 에러 처리를 해서 사용자에게 혼란을 주지 않도록 해야 한다.

=> 반드시 .then .catch 또는 try catch문으로 오류 상환 적절히 처리 해주기

 import { useQuery } from "react-query";

 function TodoList({ isActive }) {
 const { isLoading, isError, data } = useQuery("todos", getTodos); //qeury key

  if (isLoading) {
    return <p>로딩중입니다....!</p>;
  }

  if (isError) {
    return <p>오류가 발생하였습니다...!</p>;
  }

React Query가 가지고 있는 큰 장점이라 할 수 있다. Thunk를 이용하면 state에서 isLoading, isError등을 개발자가 직접 만들어줬어야 했다. 

React Query는 서버 데이터를 위한 표준을 이미 제시하고 있기 때문에 개발자들 마다의 특성에 따라 바뀔 염려가 없다.

return 문에 도착하기 전에 isLoading 또는 isError에 따라 별도의 처리를 해주기 때문에 대기상태 처리 / 오류 처리에 대한 부분도 아주 쉽게 해결된다.

 

 

4. useMutation = Post, Delete, Patch => 캐싱

❗첫번째 인자 비동기 함수는 반드시 한개여야 한다. 아니면 에러 발생

invalidate해야 하는지를 확인하고 필요시 반드시 리액트 키를 무효화 하고 다시 최신화 해주도록 한다.

import { QueryClient, useMutation } from "react-query";
...


function Input() {
...
	const queryClient = QueryClient();
	
	const mutation = useMutation(addTodo, {
	  onSuccess: () => {
	    // Invalidate and refresh
	    // 이렇게 하면, todos라는 이름으로 만들었던 query를
	    // invalidate 할 수 있어요.
	    queryClient.invalidateQueries("todos"); //qeury key
	  },
      
      
      // addTodo 사용부
      mutation.mutate(newTodo) //post API에 전달할 인자(추가할 todo)
  });

mutation.mutate( 인자 )는 반드시 한개여야 한다. 아니면 에러 발생

1. 인자는 반드시 한 개의 변수 또는 객체여야 한다.

2. mutation.mutate(인자1, 인자2) → 오류

 

.invalidateQueries("todos") => "todos"라는 query key를 가진 서버 데이터를 새로고침하지 않아도 항상 최신화 해준다. ❗따라서 query key는 반드시 unique해야 한다.

=> Input.jsx에서 값 입력으로 인해 서버 데이터가 변경됨

→ onSuccess가 일어나면 기존의 Query인 “todos”는 무효화

→ 새로운 데이터를 가져와서 “todos”를 최신화시킴

→ TodoList.jsx를 갱신함