Notice
Recent Posts
Recent Comments
Link
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
Tags
- 코드트리
- javascript
- route53
- 티스토리챌린지
- react
- vscode
- 프론트엔드
- SQL
- 웹 개발
- html
- 파이썬
- CSS
- 깃허브뱃지
- #AwsCloudClubs
- 박스 모델
- 유니티
- 코딩테스트
- 기술심화
- 학습회고
- 데이터베이스
- 유니티 모듈
- #UMC #UMC10기 #UMC 블로그챌린지 #IT동아리
- GitHub
- 코드트리조별과제
- 유니티 에디터
- HeidiSQL
- 깃허브
- 주석 단축키
- 유니티 안드로이드 빌드
- 오블완
Archives
- Today
- Total
Hello It's good to be back ^_^
[UMC 블로그챌린지] Web 파트 7주차 - useMutation과 Optimistic Update 본문
Mutation (데이터 변경)
: 클라이언트가 서버 데이터를 바꾸는 것 ex. 좋아요, 댓글 등
Pessimistic Update
: 데이터 변경을 서버 응답을 기다린 후 반영하는 것, 구현은 단순하고 정합성이 보장되지만, 사용자가 매번 로딩을 기다려야 함
Optimistic Update (낙관적 업데이트)
: 데이터 변경을 먼저 UI를 바꾸고 서버 응답으로 검증하는 것, 사용자 경험은 즉각적이지만, 실패 시 롤백 처리와 동시성 제어가 까다로워진다
useMutation()
- Mutation이 일어나면 서버에는 반영되나 화면(클라이언트)에는 반영되지 않기에 개발자는 쿼리를 실행에 실제 데이터베이스에 추가해야 한다
- 이전에는 Mutation이 일어날 때 마다 개발자는 일일히 쿼리를 수동으로 다시 실행하는 코드를 매번 직접 작성해야 했다
- useMutation은 이러한 서버에 데이터를 변경(post/put/delete)하는 작업을 표준화 했다
useMutation의 속성
| 속성 | 역할 |
| mutationFn | 실제로 서버에 변경 요청을 보내는 비동기 함수(post/put/delete 담당) ex.createTodo |
| isPending | 요청이 진행중 인지 ex.추가 중... |
| isError | 요청이 실패 했는지 |
| onSuccess | 요청이 성공한 직후 실행되는 함수 (가장 중요) |
| .mutate() | - 변경 작업을 실행하는 함수 (여기에 payload를 전달함) |
실행 흐름
const create = useMutation({
mutationKey: ['createTodo'],
mutationFn: createTodo,
// 🔥 Mutation의 핵심!
// 1. 서버 변경(POST) 성공 시 실행. (네트워크 요청 성공)
// 2. ['todos'] 키를 가진 캐시를 '만료됨(Stale)'으로 표시합니다. (invalidateQueries)
onSuccess: () => qc.invalidateQueries({ queryKey: ['todos'] }),
});
- 사용자가 todo를 작성하고 추가 버튼 클릭 → create.mutate() 실행
- createTodo 함수가 서버에 요청을 보냄 (진행 중: create.isPending = true)
- 서버 요청 성공 → onSuccess 실행
- qc.invalidateQueries({ queryKey: ['todos'] })가 실행되자마자 TanStack Query가 TodoList 컴포넌트가 사용하는 ['todos'] 데이터가 오래됐으니 업데이트하라고 표시
- TanStack Query가 자동으로 fetchTodos 함수를 재실행(Re-fetch)하여 최신 목록을 가져오고 화면에 자동을 반영
- 개발자가 수동으로 fetchTodos를 다시 호출할 필요가 없음
라이프사이클 옵션
: 데이터 변경 요청이 이루어지는 전 과정을 세밀하게 제어하는 도구들로 데이터 변경 요청에 따라 변경 전/중/후를 제어
| 옵션 | 실행 시점 | 용도 |
| onMutate | 요청이 서버로 보내지기 직전에 호출 | -낙관적 업데이트를 할 때, 요청에 따라서 UI를 먼저 바꿨는데 요청이 실패할 경우 롤백할 데이터(=context)를 미리 저장 -캐시 데이터를 즉각 변경한다 (setQueryData 이용) |
| onSuccess | 요청이 성공적으로 완료되었을 때 호출 | 데이터를 동기화함 invalidateQueries를 사용해서 목록을 자동으로 새로고침하게 만듦 |
| onError | 요청 도중 에러가 발생했을 때 호출 | -에러 메세지를 사용자에게 보여주고 onMutate에서 변경했던 데이터(=context)를 롤백할 때 사용 -context를 꺼내와서 setQueryData로 캐시 복구 |
| onSetteled | 성공과 실패여부에 상관없이 모든 작업이 끝났을 때 호출 | -마지막으로 로딩 상태를 해제하거나 최종 정리 작업을 할 때 사용 -성공 여부와 상관없이 목록 새로고침(invalidateQueries)해서 서버의 최종 상태와 클라이언트를 동기화 |
설정 옵션
: 안정성, 제어 강화
| 옵션 | 용도 |
| retry | Mutation이 실패했을 때 몇 번까지 자동으로 다시 시도할지 정함 |
| retryDelay | 재시도 사이에 얼마나 기다릴지 시간을 정함 |
| throwOnError | 에러가 났을 때 TanStack Query 내부에서 에러를 잡지 않고 밖으로 던질지 정함 |
| meta | Mutation에 대한 추가 정보를 넣음 |
Optimistic Update (낙관적 업데이트)의 장단점
장점
- 즉각적 반응으로 사용자 경험이 좋아짐
- 네트워크 지연을 무시 (사용자의 네트워크 속도와 상관없이 빠른 반응)
단점
- 서버 요청이 실패했을 경우 롤백해야 하므로 로직이 복잡해짐
- 일시적으로 클라이언트 화면과 서버의 실제 데이터가 다를 수 있음
언제 낙관적 업데이트를 사용해야 할까?
- 사용자 행동이 성공할 확률이 매우 높고 UI 피드백이 즉각적이어야 만족도가 높을 때
- 단순 데이터 변경 - 좋아요, 북마크, ToDo 완료 체크 등
- 단독 작업 - 다른 사용자와 충돌 가능성이 적은 개인적인 데이터 수정
- 지연시간이 느린 네트워크 - 사용자가 답답함을 느끼는 네트워크에서 이를 가릴 수 있음
언제 낙관적 업데이트 사용을 피해야 할까?
- 데이터의 정확성이 중요하고 실패 가능성이 빈번할 때
- 결제 및 송금 - 반드시 서버의 확정 응답 필요
- 복잡한 비즈니스 로직 - 서버의 추가적인 검증(재고 확인, 권한 체크 등)을 거쳐야만 결과가 확정되는 경우
- 충돌 가능성이 높은 동시 편집 - 여러 명이 동시에 수정해서 서버에서 데이터 병합이 복잡하게 일어나는 경우
TanStack Query 기반 구현 흐름 (onMutate → mutate → onError → onSettled)
- onMutate:
- mutate 함수가 호출될 때 즉시 실행
- 진행 중인 refetch를 취소(cancelQueries)하여 낙관적 업데이트가 덮여쓰여지지 않게 한다
- 현재 캐시 데이터를 백업(Snapshot)합니다
- setQueryData를 사용해 캐시를 새로운 값으로 강제 업데이트
- 백업된 데이터를 context로 반환합니다.
- (mutate):
- 실제 서버로 API 요청을 보낸다
- onError:
- 서버 요청이 실패했을 때 실행된다
- onMutate에서 반환한 context(스냅샷)를 사용하여 캐시를 이전 상태로 복구한다
- onSettled:
- 성공/실패 여부와 상관없이 마지막에 실행
- invalidateQueries를 호출하여 서버의 최신 데이터와 동기화(Refetch)를 진행한다
'Study > Web' 카테고리의 다른 글
| [UMC 블로그챌린지] Web 파트 4주차 - 기술심화 (0) | 2026.04.06 |
|---|---|
| [UMC 블로그챌린지] Web 파트 4주차- CS 전반적으로 훝어보기 (1) | 2026.04.05 |
| [UMC 블로그챌린지] Web 파트 2주차 useState와 useReducer에 대해 알아보기 (0) | 2026.03.24 |
| [ECC-프론트엔드 2팀] 17주차 스터디 (2) | 2025.01.25 |
| [ECC-프론트엔드 2팀] 17주차 스터디 (4) | 2025.01.16 |
