일반적으로 데이터를 업데이트할 때, 서버 응답을 기다린 후 UI를 변경한다. 하지만 낙관적 업데이트 Optimistic Update는 서버 응답을 기다리지 않고 먼저 UI를 변경한 후, 요청이 실패하면 롤백하는 방식이다.
낙관적 업데이트는 SNS의 좋아요 기능에서 자주 사용된다. 사용자가 좋아요 버튼을 누르면 즉시 UI의 변경 사항(🤍 ▶️ ❤️)을 먼저 적용하고, 서버에 요청을 보낸다. 만약 요청이 실패하면 원래 데이터(🤍)로 복구된다.
*비관적 업데이트란? : 낙관적 업데이트의 반대개념으로, 서버 응답 후 UI 갱신하는 방법을 뜻한다.
구분 | 낙관적 업데이트 | 비관적 업데이트 |
---|---|---|
UI 업데이트 시점 | 요청 직후 즉시 | 서버 응답을 받은 후 |
응답 실패 시 | 원래 상태로 롤백 | UI 변경 없음 |
속도 및 반응성 | 빠름 | 상대적으로 느림 |
적용 예시 | 좋아요 버튼, 댓글 작성 | 데이터 조회 후 렌더링 |
onMutate
: mutationFn
가 실행되기 전에 실행되는 로직onError
: mutationFn
실행 중 오류가 발견되면 실행되는 로직onSettled
: 성공/실패 여부와 관계없이 mutationFn
요청이 완료된 후 실행되는 로직onMutate
: cancelQueries
로 중복 방지, getQueryData
로 이전 데이터 반환, setQueryData
로 낙관적 업데이트 로직 실행//예시
onMutate: async ({ id, liked }) => {
//중복 방지를 위한 요청 취소
await queryClient.cancelQueries([QUERY_KEY.TODOS, id]);
//오류 발생 시 되돌려 놓을 이전 데이터 저장
const prevTodo = queryClient.getQueryData([QUERY_KEY.TODOS, id]);
//낙관적 업데이트
const updatedTodo = { ...prevTodo, liked: !liked };
queryClient.setQueryData([QUERY_KEY.TODOS, id], updatedTodo);
return { prevTodo };
}
onError
: 요청 실패시, setQueryData
를 사용하여 이전 데이터로 재설정//예시
onError: (error, _, context) => {
//요청 실패시 이전 데이터로 재설정
queryClient.setQueryData(context.prevTodo);
}
onSettled
: 요청 성공시 invalidateQueries
로 쿼리 무효화//예시
onSettled: () => {
//쿼리 무효화
queryClient.invalidateQueries([QUERY_KEY.TODOS]);
}
useTodoMutation.js
: Custom Hook으로 제작
TodoList.jsx
: mutate
함수 import
TodoList.jsx
- JSX : like버튼
에 onClick이벤트에 likeMutation
연결TanStack Query - useMutation 공식 문서
TanStack Query - Optimistic Update 공식 문서
Optimistic Update 참고 사이트