본문 바로가기
FrontEnd/React.js

React-Query에 대하여 ( useQuery, useMutation )

by 위그든씨 2022. 12. 7.

1. useMutation은 언제 필요한가?

어떤 페이지(게시판,sns 등)에서 특정 댓글을 작성했거나 삭제 했을때 router.reload()를 통한 새로고침으로 

사용자에게 보여주는 방법이 있다. 하지만 이러한 측면은 UX 측면에서 좋지 않기 때문에 새로고침 없이 업데이트 된 것을 

보여주는 react-query의 useMutation() 훅을 사용한다.

2. react-query란?

  • react-query는 리액트 애플리케이션에서 서버 상태 가져오기, 캐싱, 동기화 및 업데이트를 보다 쉽게 다룰 수 있도록 도와주며 클라이언트 상태와 서버 상태를 명확히 구분하기 위해서 만들어진 라이브러리이다.
  •  react-query hook의 종류 ( useQuery, useMutation, useInfiniteQuery )
    1. useQuery : 단순히 data를 가져오는 역할을 한다. (GET)
    2. useMutation : data를 업데이트|변경|삭제 할때 사용된다. (POST, PUT, DELETE)
    3. useInfiniteQuery: 무한 스크롤 | 페이지네이션을 제공할 때 사용되는 훅 (따로 포스팅 예정) 

3. useQuery

const {
    data, dataUpdatedAt,error,errorUpdatedAt,failureCount,failureReason,isError,isFetched,isFetchedAfterMount,isFetching,isPaused,isLoading,isLoadingError,isPlaceholderData,isPreviousData,isRefetchError,isRefetching,isStale,isSuccess,refetch,remove,status,fetchStatus,
  } = useQuery({queryKey,queryFn,cacheTime,enabled,networkMode,initialData,initialDataUpdatedAt,keepPreviousData,meta,notifyOnChangeProps,onError,onSettled,onSuccess,placeholderData,queryKeyHashFn,refetchInterval,refetchIntervalInBackground,refetchOnMount,refetchOnReconnect,refetchOnWindowFocus,retry,retryOnMount,retryDelay,select,staleTime,structuralSharing,suspense,useErrorBoundary,
  })

 

  • data GET을 위한 훅  (API를 통해 data를 가져올때)
  • 파라미터(옵션) 필수요소 -  queryKey(유니크 키), queryFn(비동기 함수-api 호출 함수) 
  • useQuery는 비동기로 작동하므로, 한 컴포넌트에서 여러개의 useQuery가 있다면 동시에 실행 되는것
  • 여러개의 비동기 query가 있다면 useQuries를 사용할 것
  • cf) 파라미터의 enabled를 사용한다면 useQuery를 동기적으로 사용 가능.
function Example() {
  const { isLoading, error, data } = useQuery(["repoData"], () =>
    axios
      .get("https://api.github.com/repos/tannerlinsley/react-query")
      .then((res) => res.data)
  );

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

 

const { data: todoList, error, isFetching } = useQuery("todos", fetchTodoList);
const { data: nextTodo, error, isFetching } = useQuery(
  "nextTodos",
  fetchNextTodoList,
  {
    enabled: !!todoList // true가 되면 fetchNextTodoList를 실행한다
  }
);
  • useQuries 를 통해 비동기 여러개 실행하기
const result = useQueries([
  {
    queryKey: ["getRune", riot.version],
    queryFn: () => api.getRunInfo(riot.version)
  },
  {
    queryKey: ["getSpell", riot.version],
    queryFn: () => api.getSpellInfo(riot.version)
  }
]);

useEffect(() => {
  console.log(result); // [{rune 정보, data: [], isSucces: true ...}, {spell 정보, data: [], isSucces: true ...}]
  const loadingFinishAll = result.some(result => result.isLoading);
  console.log(loadingFinishAll); // loadingFinishAll이 false이면 최종 완료
}, [result]);
  • unuque key 활용
const riot = {
  version: "12.1.1"
};

const result = useQueries([
  {
    queryKey: ["getRune", riot.version],
    queryFn: params => {
      console.log(params); // {queryKey: ['getRune', '12.1.1'], pageParam: undefined, meta: undefined}

      return api.getRunInfo(riot.version);
    }
  },
  {
    queryKey: ["getSpell", riot.version],
    queryFn: () => api.getSpellInfo(riot.version)
  }
]);

4. useMutation 

  • 값을 바꿀 떄 사용하는 훅. return 값은 useQuery와 동일 
  • DB에서의 insert, update, delete와 역할 비슷
  • 서버에 data 변경 작업 요청시 사용( POST, PUT, DELETE ) 
const {mutate, data,error,isError,isIdle,isLoading,isPaused,isSuccess,failureCount,failureReason,mutateAsync,reset,status,
  } = useMutation({mutationFn,cacheTime,mutationKey,networkMode,onError,onMutate,onSettled,onSuccess,retry,retryDelay,useErrorBoundary,meta})
  
mutate(variables, {onError,onSettled,onSuccess,})
const savePerson = useMutation(mutationFn);
  • mutationFn이란? 
    • promise 처리가 이루어지는 함수
    • 즉 서버에 API를 요청하는 부분
onError,onSettled,onSuccess,
  • 서버에 data 변경 요청이 성공할 경우에 추가적인 액션을 할 수 있도록 코드를 작성
const savePerson = useMutation({
    mutationFn: (person: Iperson) => axios.post('/savePerson', person),
    onSuccess: () => { // 요청이 성공한 경우
        console.log('onSuccess');
    },
    onError: (error) => { // 요청에 에러가 발생된 경우
        console.log('onError');
    },
    onSettled: () => { // 요청이 성공하든, 에러가 발생되든 실행하고 싶은 경우
        console.log('onSettled');
    }
})

 

참고 : https://jforj.tistory.com/244

 

[React] React Query의 useMutation에 대해 알아보기

안녕하세요. J4J입니다. 이번 포스팅은 React Query의 useMutation에 대해 적어보는 시간을 가져보려고 합니다. useMutation란? useMutation은 React Query를 이용해 서버에 데이터 변경 작업을 요청할 때 사용합

jforj.tistory.com

https://kyounghwan01.github.io/blog

 

react-query 개념 및 정리

react-query 개념 및 정리, react, react16, hook, useState, useRef, useMemo, useEffect, useReducer, useCallback, useQuery 동기적으로 실행

kyounghwan01.github.io

https://tanstack.com/query/v4/docs/reference/useMutation

 

useMutation | TanStack Query Docs

const { data,

tanstack.com

https://tanstack.com/query/v4/docs/reference/useQuery