[React-Query]

Duboo·2023년 11월 8일
0

REACT HOOK

목록 보기
15/16
post-custom-banner
import { QueryClient, QueryClientProvider } from "react-query";
import Router from "./shared/Router";

const queryClient = new QueryClient();

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

export default App;
  • 모든 페이지에서 리액트 쿼리를 사용하기 위해서 최상단(App.js)에서 QueryClientProvider 로 앱을 감싸준다.

  • 쿼리 인스턴스를 생성한다. const queryClient = new QueryClient();

  • 생성한 인스턴스를 넘겨준다. client={queryClient}


useQuery

  • GET 요청과 같은 Read 작업을 할 때 사용되는 Hook이다.

  • 첫번째 파라미터로 QueryKey가 들어가고 두번째 파라미터로 비동기 함수(api호출 함수)가 들어간다.

  • return값은 api의 성공여부, 실패여부, api return값을 포함한 객체이다.

  • useQuery는 비동기로 작동한다. 즉, 한 컴포넌트에 여러 개의 useQuery가 있다면 하나가 끝나고 다음 useQuery가 실행되는 것이 아닌 두개의 useQuery가 동시에 실행된다. 그러므로 여러개의 비동기 query가 있다면 useQuery보다는 useQueries를 사용하는 것이 좋다.

  • 혹은 Query Options에서 enabled를 사용하면 useQuery를 동기적으로 사용할 수 있다.

import { useQuery } from "react-query";

// 주로 사용되는 3가지 return값 외에도 더 많은 return 값들이 있다.
const { data, isLoading, error } = useQuery(queryKey, queryFn, options)

Query Key

  • ❗️QueryKey를 기반으로 데이터 캐싱을 관리한다.
  • 쿼리키는 문자열 또는 배열로 지정할 수 있다.
  • 쿼리키를 배열로 지정하면 배열의 0번 값은 string으로 다른 컴포넌트에서 부를 키를 넣어주면 되고 1번째 값은 query함수의 파라미터로 전달될 값을 넣어주면 된다.
// 문자열
useQuery('todos', ...)
// 배열
useQuery(['todos', '1'], ...)

❗️쿼리가 변수에 의존하는 경우에는 Query Key에도 해당 변수를 추가해주어야 한다.

const { data, isLoading, error } = useQuery(['todos', id], () => axios.get(`http://.../${id}`));

첫번째 파라미터로 설정한 QueryKey는 다른 컴포넌트에서도 해당 키를 사용하면 호출 가능하다.


useMutation

  • 데이터 변경 및 삭제 하는 메서드
  • POST, PUT, DELETE와 같은 변경 및 수정 작업을 할 때 사용되는 훅이다.
const data = useMutation(API 호출 함수, 콜백);
  • return 값은 useQuery와 동일하며 mutate 메서드가 추가된다.
  • mutate 메서드를 이용하면 API 요청 함수를 호출하여 요청이 이루어진다.

❗️쿼리 무효화(Invalidation)

Add 후 수동적으로 Fetch를 해줘야 화면에 보여진다는 불편함이 있다.
이 문제점을 해결하기 위해서는 쿼리 무효화(Invalidation) 를 시켜줘야 한다.
이 전에 캐싱된 쿼리를 직접 무효화 시킨 후 데이터를 새로 패칭해줄 수 있다.

import { useMutation, useQueryClient } from 'react-query';

const AddSuperHero = () => {const queryClient = useQueryClient();
  
  const addSuperHero = (hero) => {
    return axios.post('http://localhost:4000/superheroes', hero);
  };
  
  const { mutate: addHero, isLoading, isError, error } = useMutation(addSuperHero, {
    onSuccess: () => {
    // 캐시가 있는 모든 쿼리 무효화
    ✅ queryClient.invalidateQueries();
    
    // queryKey가 'super-heroes'로 시작하는 모든 쿼리 무효화
    ✅ queryClient.invalidateQueries('super-heroes');
    }
  });

  const handleAddHeroClick = () => {
    const hero = { 이름, 성별 };
    addHero(hero);
  };

  if (isLoading) {
    return <h2>Loading...</h2>;
  }

  if (isError) {
    return <h2>{error.message}</h2>;
  }
}
profile
둡둡
post-custom-banner

0개의 댓글