| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 |
- 알고리즘
- Python
- 파이썬 코테
- 99클럽
- 오블완
- 코딩테스트
- 백준
- flutter getx
- 개발자 취업
- ML
- 항해99
- 코딩테스트준비
- DP
- 파이썬
- Flutter
- 플러터
- 코테 파이썬
- react
- 코딩테스트 준비
- 개발자취업
- 티스토리챌린지
- Laravel
- vue
- 뷰
- 라라벨
- 코테
- C++
- til
- 안드로이드
- c++ 코테
- Today
- Total
잡다로그
Tanstack Query 시작하기 - 데이터 변경하기, useMutation (응답 처리, 변수 전달 등) 본문
Mutations
쿼리(useQuery)와 달리, Mutation은 데이터를 생성/업데이트/삭제하거나 서버 사이드 이펙트를 수행하는 데 사용된다.
* React에서 사이드 이펙트란, 함수 내에서 동일한 입력에 대해 같은 결과를 보장할 수 없도록 하는 것이다. 서버에서 API 호출, 쿠키 이용 등 함수 실행 과정에서 외부의 값을 변경(add, update, delete)하는 것이다. 이 사이드 이펙트를 처리하기 위한 hook이 useEffect이다.
useMutation
const mutation = useMutation({
mutationFn: (newTodo) => {
return axios.post('/todos', newTodo)
},
})
필수인자
- mutationFn: default mutation 함수가 정의되지 않은 경우 필수이다. 비동기 작업을 수행하고 Promise 객체를 반환하는 함수이다.
반환값은 다음과 같은 값을 포함한다.
- mutate: 변수를 전달하여 mutation을 실행하는 함수이며, 추가 콜백 옵션을 연결할 수 있다.
- mutateAsync: mutate와 유사하지만, Promise를 반환하여 await로 처리할 수 있다.
- status: 현재 mutation의 상태를 나타낸다. idle(실행 전 초기), error, success, pending(실행 중)
- isIdle, isPending, isSuccess, isError: status 값에 따라 파생된 boolean 상태 변수이다. mutation은 언제든 이 중 하나의 상태에만 있을 수 있다.
- data: mutationFn의 반환값. 성공 여부만 반환하면 true와 같은 값, 업데이트된 데이터를 반환하면 바뀐 데이터를 포함한다.
예제: 서버에 새로운 todo 추가
function App() {
const mutation = useMutation({
mutationFn: (newTodo) => {
return axios.post('/todos', newTodo)
},
})
return (
<div>
{mutation.isPending ? (
'Adding todo...'
) : (
<>
{mutation.isError ? (
<div>An error occurred: {mutation.error.message}</div>
) : null}
{mutation.isSuccess ? <div>Todo added!</div> : null}
<button
onClick={() => {
mutation.mutate({ id: new Date(), title: 'Do Laundry' })
}}
>
Create Todo
</button>
</>
)}
</div>
)
}
위의 예제와 같이, mutate 함수를 호출하며 변수나 객체를 전달할 수 있다.
mutations은 onSuccess 옵션, Query Client의 invalidateQueries 함수와 setQueryData함수와 함께 사용하면 아주 강력해진다.
* mutation 함수는 비동기 함수이므로, React 16을 포함한 이전 버전에서는 이벤트 콜백에서 바로 사용할 수 없다. onSubmit에서 이벤트에 접근하려면 mutate를 다른 함수로 감싸주어야 한다. 이것은 React의 event pooling 때문!
Mutation 변수 전달
정보를 추가하거나 수정할 때와 같이 다양한 정보를 파라미터로 전달해야 하는 때가 있다. 그러나 useMutation은 하나의 변수만 받을 수 있다. 여러 정보를 보내기 위해서는 객체를 사용해서 감싸주어야 한다.
const mutation = useMutation({
mutationFn: (title, body) => updateTodo(title, body), // 🚨 틀린 문법이고, 동작하지 않음
})
mutation.mutate('hello', 'world')
const mutation = useMutation({
mutationFn: ({ title, body }) => updateTodo(title, body), // ✅ 여러 변수들을 위해 object(객체)를 활용한다.
})
mutation.mutate({ title: 'hello', body: 'world' })
동작을 반영한 새로고침
Query Client의 invalidateQueries함수와 사용했을 때 강력해진다는 것이 바로 아래와 같이 콜백 함수에서 활용할 수 있기 때문이다.
const useUpdateTodo = () =>
useMutation({
mutationFn: updateTodo,
onSuccess: () => {
// ✅ 항상 할 일 목록을 무효화 한다.
queryClient.invalidateQueries({
queryKey: ['todos', 'list'],
});
},
});
useQuery를 다루며 보았던 함수이다. '새로고침'의 개념이라고 생각하면 좋다.
변형 후 응답에 접근하기: mutate() 와 mutateAsync()
useMutation을 사용하기 전에는, try-catch문 내부에서 await 키워드와 함께 API 함수를 호출해주었었다. 리팩토링을 하며 도입 중이기에, 지워도 되나 싶어 검색해보니 try-catch문과 함께 써도 되지만 아무 의미가 없고 대신 mutateAsync을 활용하라고 한다.
mutate는 아무것도 반환하지 않지만, mutateAsync는 성공 시 변형의 결과를 포함하는 프로미스를 반환한다. 그래서 변형 응답에 접근해야 할 때 mutateAsync를 사용할 수 있다.
const mutation = useMutation({ mutationFn: addTodo });
try {
const todo = await mutation.mutateAsync(todo);
console.log(todo);
} catch (error) {
console.error(error);
} finally {
console.log("done");
}
그러나 mutate를 사용해도 콜백을 통해 data나 error에 접근할 수 있기 때문에 항상 mutate로 사용하기를 권장한다.
muateAsync는 프로미스 제어권을 개발자에게 넘기기 때문에, 수동으로 오류를 잡아야 하고 미처 처리하지 못한 프로미스를 거부받을 수도 있다. 따라서 정말로 프로미스가 필요한 경우(여러 변형을 동시에 발동시키고 모두 완료되기까지 기다리고 싶거나, 콜백 지옥에 빠질 수 있는 종속적인 변형이 있는 경우 등)에 필요할 수 있습니다.
const onSubmit = () => {
// ✅ onSuccess를 통해 응답에 접근한다.
myMutation.mutate(someData, {
onSuccess: (data) => history.push(data.url),
});
};
const onSubmit = async () => {
// 🚨 작동하지만, 에러 처리가 없다.
const data = await myMutation.mutateAsync(someData);
history.push(data.url);
};
const onSubmit = async () => {
// 😕 문제는 없는 방법이지만 장황하다.
try {
const data = await myMutation.mutateAsync(someData);
history.push(data.url);
} catch (error) {
// 아무것도 하지 않는다.
}
};

참고:
https://react-query.kro.kr/docs/guides-and-concepts/mutations
Mutations – React Query 한글 문서
Nextra: the next docs builder
react-query.kro.kr
https://velog.io/@hamjw0122/useMutation-1-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0
🏵️ React-Query 제대로 사용해보기 (1) useMutation
useMutation이란?
velog.io
Mastering Mutations in React Query
Learn all about the concept of performing side effects on the server with React Query.
tkdodo.eu
highjoon-dev
highjoon's dev-log
highjoon-dev.vercel.app
'Web > React' 카테고리의 다른 글
| Tanstack Query - 서버 컴포넌트 데이터 prefetching (SSR) (0) | 2025.04.14 |
|---|---|
| 비동기, Promise, async/await (ft. useQuery의 queryFn) (0) | 2024.11.30 |
| [React.js] useCallback - useMemo와의 연관성, 4가지 사용법 (2) | 2024.11.13 |
| Tanstack Query 시작하기 - 데이터 불러오기, 새로고침 (useQuery, queryClient.invalidateQueries 등) (0) | 2024.11.11 |
| [React.js] Props대신 Context 활용하기, useContext (ft. Prop drilling) (0) | 2024.09.27 |