-
React-Query에 대하여 ( useQuery, useMutation )FrontEnd/React.js 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 )
- useQuery : 단순히 data를 가져오는 역할을 한다. (GET)
- useMutation : data를 업데이트|변경|삭제 할때 사용된다. (POST, PUT, DELETE)
- 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> ); }
- useQuery 동기적 실행하는 법 (enabled)
- 출처: https://kyounghwan01.github.io/blog
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
https://kyounghwan01.github.io/blog
'FrontEnd > React.js' 카테고리의 다른 글
[React] 컴포넌트가 데이터를 다루는 3가지 방법 (0) 2023.06.21 [React] 데이터를 실시간으로 갱신하기(useSWR, setInterval,useQuery) (0) 2023.03.19 [React.js] React Query 에 대해 (feat. SWR 과의 차이) -v3 (0) 2022.12.30 [React.js] video 태그에 동적 값 할당 (0) 2022.12.29 [React & 브라우저] 브라우저의 동작 과정 (feat. 렌더링 실행) (3) 2022.12.23