FrontEnd/React.js

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

위그든씨 2022. 12. 7. 17:11

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