낙관적 업데이트
낙관적 업데이트란?
- 서버 응답이 오기 전, 사용자가 예상하는 결과를 미리 화면에 반영해주는 방식
- 서버가 성공적으로 사용자의 요청을 처리할 것이라 낙관적으로 예상하여 UI 변경
- 빠른 반응으로인해 사용자 경험을 개선
- 비동기 상태 관리에 사용됨
- 실제 네트워크 응답시간을 노출하지 않기 때문에 UX 지연 최소화
작동 방식
- 변경 전 스냅샷(snapshot) 저장
- 실패 시 복구할 수 있도록, 변경 전의 상태를 별도로 보존
- 클라이언트 상태 즉시 갱신
- 예상 성공 결과를 기반으로 캐시, 상태 컨테이너, UI등을 즉각 수정
- 서버에 뮤테이션 요청
- 응답 처리
- 성공 : 캐시 재검증(서버에서 최신 데이터 받아 재동기화)
- 실패 : 스냅샷을 이용해 상태를 원복(rollback)
낙관적 업데이트 예시
- 좋아요 버튼 클릭 : likesCount를 서버 요청 성공 전에 +1시키고 실패시 -1로 롤백
- 아이템 삭제 : 리스트에서 아이템을 즉시 제거, 서버 실패 시 다시 리스트에 복구
- 댓글 작성 : 새 댓글을 클라이언트 캐시에 즉시 추가. 서버 실패 시 제거
Tanstack Query와 낙관적 업데이트
- Tanstack Query(React Qeury)를 사용하지 않아도 가능
- 프론트엔드 상태 관리 패턴일 뿐 Tanstack Query의 고유 기능이 아님
- Tanstack Query는 헬퍼 도구
그럼에도 불구하고 Tanstack Query를 많이 사용
- 낙관적 업데이트의 흐름을 편리하게 해주는 API(onMutate, onError,onSettled)를 제공
- 클라이언트 상태를 서버와 자동으로 동기화
- 수동으로 스냅샷을 저장하고 롤백하고 다시 refresh하는 코드를 Tanstack Query가 대신 해줌
- REST API요청을 여러 컴포넌트가 사용하는 경우 한번에 처리가능ㅋ
- 캐싱과 서버 재검증까지 Tanstack Query
- 상태 동기화와 낙관적 업데이트를 같이 안전하게 작동
Tanstack Query없이 직접 구현 예시
const [likes, setLikes] = useState(0);
const handleLike = async () => {
const prevLikes = likes;
setLikes(prev => prev + 1);
try {
await fetch('/api/like', { method: 'POST' });
} catch (e) {
setLikes(prevLikes);
}
};