React-query 공식문서에서는 다음과 같이 설명하고 있습니다.
fetching, caching, 서버 데이터와의 동기화를 지원해주는 라이브러리
Context , Redux 를 사용하다가 react-query 를 우연히 접하게 되어 정리하게 되었습니다.
좋은 기술이 있나 서칭중 kakao - 2021 컨퍼런스에서 언급된 내용 중, 아래와 같은 내용이 있었습니다.
「if(kakao)2021 - 카카오페이 프론트엔드 개발자들이 React Query를 선택한 이유」
🥥 React Query는 React Application에서 서버 상태를 불러오고, 캐싱하며,
지속적으로 동기화하고 업데이트하는 작업을 도와주는 라이브러리입니다.
🥥 복잡하고 장황한 코드가 필요한 다른 데이터 불러오기 방식과 달리
React Component 내부에서 간단하고 직관적으로 API를 사용할 수 있습니다.
🥥 더 나아가 React Query에서 제공하는 캐싱, Window Focus Refetching 등 다양한 기능을 활용하여
API 요청과 관련된 번잡한 작업 없이 “핵심 로직”에 집중할 수 있습니다.
Window Focus Refetching
간단히 말해서, 사용자가 웹 앱의 다른 페이지로 이동했다가 다시 돌아올 때,
해당 페이지가 화면에 나타나게 되면 자동으로 데이터를 리패치합니다.
이러한 좋은 기능이 있다는 것을 알고 정리하기 시작했습니다.
정말 간단하게 말하자면 React-query는 React에서 비동기를 쉽게 다루게 해주는 라이브러리입니다.
글로벌 상태관리 라이브러리( Redux, MobX, recoil... ) 없이 서버에서 데이터를 가져오고
그 데이터를 모든 컴포넌트에서 사용 가능하게 캐싱하거나, 그 이외에도 주기적으로 데이터 패칭,
Optimistic Updates(낙관적인 업데이트) 등을 지원합니다.
Optimistic Updates
데이터 변경을 요청 후 실제로 요청이 성공하기 전 미리 UI만 변경한 뒤,
서버의응답에 따라 다시 롤백하거나 업데이트 된 상태로 UI를 놔두는 것
React-Query의 가장 큰 장점 중 하나라고 생각하는 부분은 데이터를 캐싱한다는 점입니다.
캐싱이란 특정 데이터의 복사본을 저장하여 이후 동일한 데이터를 재사용 한다는 뜻입니다.
React-Query는 캐싱을 통해 동일한 데이터에 대한 반복적인 비동기 데이터 호출을 방지하고,
이는 불필요한 API 콜을 줄여 서버에 대한 부하를 줄이는 좋은 결과를 가져옵니다.
💡여기서 궁금한 것은 데이터가 최신의 것인지 아닌지에 대한 것입니다.
만일 서버 데이터를 불러와 캐싱한 후, 실제 서버 데이터를 확인했을 때 서버 상에서 데이터의 상태가 변경되어있다면, 사용자는 실제 데이터가 아닌 변경 전의 데이터를 바라볼 수밖에 없게 됩니다. 이는 사용자에게 잘못된 정보를 보여주는 에러를 낳습니다.
참고로, React-Query에서는 최신의 데이터를 fresh한 데이터, 기존의 데이터를 stale한 데이터라고 말합니다.
위와 같은 에러를 발생시키지 않는 좋은 캐싱 기능을 제공한다는 것은 결국 필요한 상황에 적절하게 데이터를 갱신해줄 수 있다는 말과 같습니다. 그럼 그런 상황은 언제일까요??
크게 보면 위의 3가지로 나눌 수 있습니다.
이를 위해 React-Query에서는 기본적인 아래의 옵션들을 제공합니다.
refetchOnWindowFocus, //default: true
refetchOnMount, //default: true
refetchOnReconnect, //default: true
staleTime, //default: 0
cacheTime, //default: 5분 (60 * 5 * 1000)
❗위의 옵션들을 통해 우리는 React-Query가 어떤 시점에 데이터를 Refetching하는지 알 수 있다.
브라우저에 포커스가 들어온 경우(refetchOnWindowFocus)
새로운 컴포넌트 마운트가 발생한 경우(refetchOnMount)
네트워크 재연결이 발생한 경우(refetchOnReconnect)
💡 staleTime? 💡 cacheTime ?
💡 staleTime
staleTime은 데이터가 fresh → stale 상태로 변경되는 데 걸리는 시간입니다.
fresh 상태일 때는 Refetch 트리거(위의 3가지 경우)가 발생해도 Refetch가 일어나지 않습니다.
기본값이 0이므로 따로 설정해주지 않는다면 Refetch 트리거가 발생했을 때 무조건 Refetch가 발생합니다.
예를 들어, staleTime
을 10 * 60 * 1000 (10분)
으로 설정하면 , 해당 데이터는 10분동안 리패치 되지 않습니다.
하지만 10분이 지나 위의 3가지 경우에 해당한다면 리패치 하게 됩니다.
💡cacheTime
cacheTime은 데이터가 inactive한 상태일 때 캐싱된 상태로 남아있는 시간입니다.
즉 데이터를 사용하는 페이지나 컴포넌트가 사라질 때 해당 데이터는 비활성화 됩니다.
특정 컴포넌트가 unmount(페이지 전환 등으로 화면에서 사라질 때) 되면 사용된 데이터는 inactive상태로 바뀌고, 이때 데이터는 cacheTime만큼 유지됩니다.
cacheTime 이후 데이터는 가비지 콜렉터로 수집되어 메모리에서 사라지게 됩니다.
여기서 가장 중요한 점은 만일 cacheTime이 지나지 않았는데 해당 데이터를 사용하는 컴포넌트가 다시 mount되면, 새로운 데이터를 fetch해오는 동안 캐싱된 데이터를 보여줍니다.
즉, 캐싱된 데이터를 계속 보여주는게 아니라 fetch하는 동안 임시로 보여준다는 것입니다!!
이외에도 사용자가 특정 이벤트가 발생했을 때 Refetching을 하도록 설정해줄 수 있습니다.
React-Query의 이러한 기능들을 통해 사용자는 언제나 최선의 데이터를 제공받게 됩니다.
일반적으로 cacheTime은 staleTime과 함께 사용됩니다.
const { data } = useQuery('myQueryKey', fetchDataFunction, {
staleTime: 10 * 60 * 1000, // 10분
cacheTime: 30 * 60 * 1000, // 30분
});
위의 예시에서는 데이터는 최소 10분 동안은 만료되지 않고, 캐시에는 최대 30분 동안 유지됩니다.
이 기간이 지나면 만료된 데이터를 새로운 데이터로 업데이트합니다.
즉 10분동안은 어떤 방법을 사용해도 데이터가 리패치 되지 않지만, 10분이 경과되면 Refetch 트리거(위의 3가지 경우)가 발생하면 리패치가 되고 만약에 데이터를 사용하고 있는 페이지에서 30분 동안 떠나지 않는다면 React-query 는 자동적으로 데이터를 최신 데이터로 리패치 해서 보여주기 때문에 새로고침 할 필요가 없습니다.
프로젝트의 규모가 커지고 관리해야할 데이터가 넘치다 보면, Client 에서 관리하는 데이터와 Server 에서 관리하는 데이터가 분리될 필요성을 느낍니다.
🍲 Client Data: 모달 관련 데이터, 페이지 관련 데이터 등등..
🍲 Server Data: 사용자 정보, 비즈니스 로직 관련 정보 등등..
간단하게 생각해서 비동기 API 호출을 통해 불러오는 데이터들을 Server 데이터라고 할 수 있습니다.
실제 Client 데이터의 경우 Redux, Recoil, mobX와 같은 전역 상태 관리 라이브러리들을 통해 잘 관리되어오고 있으나, 문제는 이러한 라이브러리들이 Server 데이터까지도 관리를 해야하는 상황이 발생한다는 것입니다.
위의 상태 관리 라이브러리에도 비동기 함수를 처리하는 로직이 물론 존재합니다.
그러나 이들이 Client 데이터와 Server 데이터를 완벽히 분리하여 관리에 용이하도록 충분한 기능이 지원된다고 보기 어렵습니다.
즉 위의 라이브러리들은 Client 데이터를 관리하는데 로직이 집중되어있기 때문에, Server 데이터까지 효율적으로 관리하기에는 한계가 분명합니다.
const { data } = useQuery('todos', queryFn, {
onSuccess: (fetchedData) => {
// 쿼리 성공 시 실행되는 함수
},
onError: (error) => {
// 쿼리 실패 시 실행되는 함수
},
});
예시에서는 컴포넌트 내부에서 위와 같은 로직을 통해 Server 데이터를 가져오고 있는데, 이때 onSuccess와 onError 함수를 통해 fetch 성공과 실패에 대한 분기를 아주 간단하게 구현할 수 있습니다.
이는 Server 데이터를 불러오는 과정에서 구현해야할 추가적인 설정들을 진행할 필요가 없다는 이야기입니다.
👉 즉, Client 데이터는 상태 관리 라이브러리가 관리하고, Server 데이터는 React-Query가 관리하는 구조라고 생각하면 됩니다.
이를 통해 우리는 Client 데이터와 Server 데이터를 온전하게 분리할 수 있다.
🔎 물론 여기서 React-Query가 가져온 Server 데이터를 상태 관리 라이브러리를 통해 전역 상태로 가져올 수도 있는 건 사실입니다. 그러나 refetch가 여러 번 일어나는 상황에 매번 Server 데이터를 전역 상태로 가져오는 것이 옳은지 판단하는 것은 그때그때 다릅니다. 개발하는 서비스의 상황에 맞게 잘 선택해보도록 합시다.
React-Query에서는 공식적으로 react-query/devtools 를 통해 Devtool을 지원합니다. 개발 모드에서만 사용하며, devtools를 통해 좀 더 확실하게 데이터의 흐름을 파악할 수 있습니다.
사용법은 공식 사이트에 가면 사용법이 나와 있습니다.
SWR라는 유명한 라이브러리 또한 devtools를 사용할 수 있으나, 서드 파티 라이브러리를 이용해야 합니다 ( 저는 한번도 쓰지 않았습니다 ㅎㅎ.. 알고만 있을뿐..)
React-Query에는 getPreviousPageParam, fetchPreviousPage, hasPreviousPage 와 같은 다양한 페이지 관련 기능이 존재해 이를 이용해 무한 스크롤을 쉽게 구현할 수 있습니다.
React-Query에서는 select 키워드를 사용해 raw data로부터 원하는 데이터를 추출하여 반환할 수 있다. 아래 코드로 살펴보자.
import { useQuery } from 'react-query'
function User() {
const { data } = useQuery('user', fetchUser, {
select: user => user.username,
})
return <div>Username: {data}</div>
}
👆 위의 예시처럼 select 를 통해 원하는 데이터에 접근한 뒤 추출이 가능합니다.
React-query는 쿼리가 업데이트될 때만 refetch를 진행합니다.
또한 여러 컴포넌트에서 동일한 쿼리를 사용하는 경우 한번에 묶어 업데이트를 진행합니다.
이를 통해 렌더링 퍼포먼스를 개선해줍니다.
React-query는 지정된 시간(기본 5분)동안 쿼리가 사용되지 않는다면 자동으로 메모리 해제를 하는 Auto Garbage Collection을 통해 메모리를 관리해줍니다.
React-Query는 기본적으로 컴포넌트를 감싸는 별도의 Provider가 필요해 이를 설정해야 합니다.
별도로 감싸야 하는 부분은 시간이 그렇게 많이 들지는 않지만, 귀찮다는 부분이 있습니다.
러닝커브
어떤 새로운 기술, 도구, 언어, 또는 개념을 학습하는 데 소요되는 시간과 노력의 경험적인 패턴
초기에 배워야 하는 부분이 많고 어렵기 때문에 시간이 많이 소요된다는 부분이 있습니다.
하지만 배워두면 쉽게 사용할 수 있고 이해하기도 쉬워지기 때문에 단점아닌 장점이라고도 생각하는 부분입니다.
설치
react-query v4 버전을 기반으로 하고 있습니다.
버전 4에서는 React-query가 아닌 TanStack Query로 불린다.
React Query 패키지와 http 통신을 위한 axios 패키지를 설치합니다.
$ npm i @tanstack/react-query
$ npm i axios
React Query를 사용 하기 위해선 우선 사용하고자 하는 컴포넌트를
QueryClientProvider 컴포넌트로 감싸주고 QueryClient 값을 Props로 넣어줘야 합니다.
앱 전체에서 사용하고자하면 최상위 컴포넌트에 감싸주면됩니다.
import React from 'react';
import './App.css';
import { QueryClientProvider, QueryClient } from '@tanstack/react-query';
import { ReactQueryDevtools } from "react-query/devtools"; //사용하려면 추가
const queryClient = new QueryClient();
const App = () => {
return (
<QueryClientProvider client={queryClient}>
<div className="App"></div>
</QueryClientProvider>
);
};
export default App;
useQuery
를 사용하여 데이터를 가져올 때 인자로 queryKey
와 queryFn
을 설정할 수 있습니다.
queryKey
는 데이터를 식별하는 고유한 키이며, queryFn
은 데이터를 가져오는 함수입니다.
useMutation
을 사용import { useQuery } from 'react-query';
const { data, error, isLoding } = useQuery({
queryKey: ['todos'],
queryFn: fetchTodoList
})
react-query 에서 데이터를 가져오는 방법은 useQuery 를 사용해야 합니다.
첫번째 인자로는 무조건 배열로 감싸서 이름을 정의해야 합니다.
두번째 인자로는 데이터를 받아오는 함수를 넣어줍니다. 예를 들어 axios 로 데이터를 받아오는 함수를 말합니다.
react-query 에 장점은 error, isLoding 처럼 객체를 반환해 줍니다.
이걸 이용해서 데이터를 가져올 때 특정 작업을 수행할 수 있습니다.
if(isLoding){
return (
<div>Lodaing....</div>
)
}
Dynamic Queries
배열을 사용하면 동적으로 쿼리 키를 생성하기가 더 쉽습니다.
배열 내에 변수를 포함하고 원하는 만큼 동적으로 요소를 추가할 수 있습니다.
이것은 동적 쿼리를 생성할 때 훨씬 유연하게 대응할 수 있게 해줍니다.Consistency
배열로 감싸면 쿼리 키의 형식이 일관적으로 유지됩니다.
모든 쿼리 키가 배열로 감싸지므로 혼란을 줄일 수 있습니다.
useQuery() 는 비동기적으로 작동합니다.
한 컴포넌트 내에서 다수의 useQuery가 존재한다면, 하나의 useQuery 가 실행된 후 다음의 useQuery 가
실행되는 것이 아니라, 다수의 useQuery 가 동시에 실행됩니다.
따라서 이와 같이 다수의 useQuery 가 존재할 경우, Query Options 에서 "enabled" 를 사용하면 useQuery 를 동기적으로 사용할 수 있습니다.
const usersQuery = useQuery({
queryKey: ['users'],
queryFn: fetchUsers,
enabled: !!usersQuery
});
const todosQuery = useQuery({
queryKey: ['users'],
queryFn: fetchUsers,
enabled: !!usersQuery
});
const postsQuery = useQuery({
queryKey : 'posts',
queryFn : fetchPosts,
enabled: !!todosQuery
});
이렇게 설정하면 동기적으로 usersQuery ➡ todosQuery ➡ postsQuery 로 실행됩니다.
React Query의 다양한 옵션들을 예시 코드와 함께 설명해드리겠습니다.
아래의 예시 코드에서는 React Query를 사용하며, useQuery
훅을 중심으로 예시를 제공합니다.
import { useQuery } from '@tanstack/react-query';
import axios from 'axios';
const todo = () => {
const fetchData = async () => {
const response = await axios.get('주소');
return response.data;
}
const { data, isLoding, isError, error } = useQuery({
queryKey: ['todos', user],
queryFn: fetchData,
cacheTime: 60000, // 쿼리 데이터를 캐싱할 시간을 밀리초 단위로 설정합니다. (1분)
staleTime: 30000, // 이 시간 내에서는 캐시된 데이터를 사용하고, 그 이후에 재패치됩니다
retetchInterval: 10000, // 설정하면 일정 간격으로 쿼리가 자동으로 리패치됩니다. (10초)
refetchOnWindowFocus: false, // 해당 사이트에서 다른 곳으로 갔다가 돌아오면 이 함수 실행
retry: 0 // 데이터 불러오기 실패시 재호출 몇번 할지
});
// 데이터를 가져오고 있는 중일 때
if(isLoding) {
return <div>로딩중입니다..</div>
}
// 데이터 가져오기를 실패했을 때
if(isError) {
return <div>에러 발생 : {error.message}</div>
}
/*
만약 const {data, status, ..} = useQuery(..
isLoading, isSuccess와 같은 상태를 status로 한번에 처리 가능
if (status === "loading") {
return <span>Loading...</span>;
}
if (status === "error") {
return <span>Error: {error.message}</span>;
}
*/
return (
<ul>
{data.map(todo => (
<li key={todo.id}>{todo.title}</li>
))}
</ul>
);
}
queryKey:
const { data } = useQuery({queryKey : ['todos', userId], queryFn: fetchData});
queryKey
는 쿼리를 고유하게 식별하는 키입니다.
위의 코드에서 ['todos', userId]
로 설정되었으며,
'todos'는 쿼리 종류를 식별하고 userId
는 변수로 쿼리 함수에 전달됩니다.
이렇게 정의하면 동일한 쿼리 종류라도 userId 의 값의 따라 식별키를 재각각 사용할 수 있습니다.
enabled:
const { data } = useQuery('todos', queryFn, { enabled: someCondition });
enabled
를 false
로 설정하면 쿼리가 자동으로 시작되지 않고,
나중에 enabled 의 값을 이용하여 수동으로 설정할 수 있습니다.
기본값을 enabled 는 true 로 설정되어 있습니다.
예시 코드
const isQueryEnabled = true;
const { data } = useQuery('todos',queryFn,{enabled: isQueryEnabled);
//...
return (
<div>
{/* 어떤 버튼을 누르거나 조건을 만족할 때만 쿼리를 실행하도록 설정 */}
<button onClick={() => setIsQueryEnabled(true)}>
Enable Query
</button>
<button onClick={() => setIsQueryEnabled(false)}>
Disable Query
</button>
</div>
);
과 같은 코드를 넣어줄 수 있습니다.
현재 쿼리 상태를 확인하는 작업은 디버깅이나 특정 로직에서 필요한 경우에 사용됩니다. 대부분의 상황에서는 각 쿼리의 성공, 실패, 로딩 등의 상태에 따라 컴포넌트를 조건부 렌더링하는 것이 일반적입니다.
import { useQueryClient } from 'react-query';
// 이 함수를 사용해서 쿼리에 대해 접근할 수 있습니다.
const queryClient = useQueryClient();
const specificQuery = queryClient.find('exampleQueryKey');
const allQueries = queryClient.findAll('exampleQueryKey');
const unsubscribe = queryClient.subscribe((newQueries) => {
console.log('Queries updated:', newQueries);
});
// 언제든지 구독 해제 가능
unsubscribe();
// 특정 쿼리 클리어
queryClient.clear('exampleQueryKey');
// 모든 쿼리 클리어
queryClient.clear();
useMutation
은 React Query에서 API 호출 또는 데이터 변경을 위한 훅으로,
주로 데이터를 수정하거나 업데이트하기 위해 사용됩니다.
이 훅은 다음과 같은 옵션을 받습니다
mutationKey
: 이 옵션은 해당 mutation을 식별하는 고유한 키입니다.mutationFn
: 이 옵션은 API 호출 또는 실제로 데이터 변경을 수행하는 함수를 나타냅니다.onMutate
: 이 옵션은 mutation이 시작될 때 호출되는 함수로, optimistic updates와 같은 동작을 수행하기 위해 사용됩니다.onSuccess
: 이 옵션은 mutation이 성공적으로 완료될 때 호출되는 함수입니다.onError
: 이 옵션은 mutation 실행 중에 오류가 발생했을 때 호출되는 함수입니다.onSettled
: 이 옵션은 mutation이 성공 또는 실패에 관계없이 완료될 때 호출되는 함수입니다.여기서 axios를 사용한 useMutation
의 예시 코드를 보여드리겠습니다.
코드 예시에서는 createTodo
라는 API 호출을 실행하고, 해당 코드에 대한 설명도 함께 제공하겠습니다:
import { useMutation } from 'react-query';
import axios from 'axios';
function TodoForm() {
const createTodoMutation = useMutation({
mutationKey: ['updateTodo'],
mutationFn: (newTodo) => { return axios.post('/api/todos', newTodo) },
onSuccess: () => { console.log('Todo created successfully'); },
onError: (error) => { console.error('Error creating todo:', error); },
onSettled: () => {},
})
const handleSubmit = (e) => {
e.preventDefault();
const newTodo = { text: 'New todo', completed: false };
createTodoMutation.mutate(newTodo);
};
return (
<form onSubmit={handleSubmit}>
<button type="submit">Create Todo</button>
</form>
);
}
위 코드의 주요 동작은 다음과 같습니다.
useMutation
훅을 사용하여 createTodoMutation
을 생성합니다.mutationFn
에는 axios를 이용하여 API 호출을 정의합니다. 이 함수는 newTodo
를 받아 Todo를 생성합니다.onMutate
함수는 mutation이 시작될 때 호출됩니다. 이 예시에서는 옵티미스틱 업데이트를 위해 이전 데이터를 저장하고 변경 이전 데이터로 업데이트합니다.onSuccess
함수는 mutation이 성공했을 때 호출됩니다. 여기에서는 성공 메시지 또는 다른 동작을 수행할 수 있습니다.onError
함수는 mutation 실행 중 오류가 발생했을 때 호출됩니다. 에러 처리 또는 메시지를 출력할 수 있습니다.onSettled
함수는 mutation이 완료되면 실패하든 성공하든 함수를 실행시켜 줍니다 // mutation 실행 시 호출될 함수 (옵티미스틱 업데이트 등을 수행)
onMutate: (variables) => {
// 이 예시에서는 로컬 상태로 변경 전의 데이터를 저장
const prevData = queryClient.getQueryData('todos');
// 변경 전 데이터로 업데이트
queryClient.setQueryData('todos', (oldData) => [...oldData, variables]);
// 변경 전 데이터를 반환
return prevData;
}
import React, { useCallback } from 'react';
import axios from 'axios';
import { useQuery, useMutation, useQueryClient } from 'react-query';
interface TestData {
name: string;
age: number;
}
const Test: React.FC = () => {
const queryClient = useQueryClient();
// 데이터를 가져올 함수 정의
const fetchData = useCallback( async () => {
const response = await axios.get<TestData[]>('http://localhost:4000/api/test');
return response.data;
}, []);
const postData = useCallback( async (newData: TestData) => {
const response = await axios.post<TestData[]>('http://localhost:4000/api/test', newData);
return response.data;
}, []);
// useQuery 사용
const { data, error, isLoading } = useQuery<TestData[]>({
queryKey: ['users'],
queryFn: fetchData
})
const postDataMutation = useMutation({
mutationFn: postData,
onMutate: (newData) => {
// 이 예시에서는 로컬 상태로 변경 전의 데이터를 저장
const prevData = queryClient.getQueryData<TestData[]>('users');
// 변경 전 데이터로 업데이트
queryClient.setQueryData('users', (oldData: TestData[] | undefined) => [...(oldData || []), newData]);
// 변경 전 데이터를 반환
return prevData;
},
onError: (error) => {
console.error('뮤테이션 실패:', error);
},
onSettled: (data) => {
console.log('뮤테이션 완료:', data);
},
});
// 정보를 보내는 메서드 정의
const handlePostData = () => {
const newData: TestData = {
name: '새로운유저이름',
age: 26,
};
postDataMutation.mutate(newData);
};
if (isLoading) return <div>Loading....</div>;
if (error) return <div><p>에러가 발생했습니다.</p></div>;
return (
<div className="test">
{data?.map((item, index) => (
<li key={index}>{item.name}</li>
))}
<button onClick={handlePostData}>새 데이터 추가</button>
</div>
);
};
export default Test;
여기서 이코드를 보면 이상한 점을 볼 수 있습니다.
const postDataMutation = useMutation({
mutationFn: postData,
onMutate: (newData) => {
// 이 예시에서는 로컬 상태로 변경 전의 데이터를 저장
const prevData = queryClient.getQueryData<TestData[]>('users');
// 변경 전 데이터로 업데이트
queryClient.setQueryData('users', (oldData: TestData[] | undefined) => [...(oldData || []), newData]);
// 변경 전 데이터를 반환
return prevData;
},
postData 에 매개변수를 넣어주지 않는 모습을 볼 수 있습니다. 왜 그럴까요?
useMutation
훅은 기본적으로 설정된 mutationFn
함수를 호출할 때
매개변수를 자동적으로 전달할 수 있습니다.
즉, postData
함수가 useMutation
에 전달된 mutationFn
으로 사용되면 useMutation
훅을 사용하여 호출 시에 인자를 전달할 수 있습니다.
예를 들어, 다음과 같이 mutationFn
함수와 함께 useMutation
를 사용하면
const postDataMutation = useMutation(postData);
postDataMutation
을 호출할 때 자동으로 postData
함수에 매개변수를 전달할 수 있습니다.
postDataMutation.mutate({ name: '새로운유저이름', age: 26 });
여기서 { name: '새로운유저이름', age: 26 }
객체가 postData
함수의 매개변수로 전달됩니다.