Next.js
React 낙관적 업데이트를 되돌릴 때 원본 상태를 보존한 짧은 튜토리얼
좋아요 API가 실패해도 정확히 이전 화면으로 돌아가도록 만든 구현을 정리했다
빠른 화면이 오히려 어색해진 순간
좋아요 버튼을 누르면 서버 응답 뒤 숫자를 바꾸도록 처음 구현했다. 느린 모바일에서 클릭이 먹지 않은 것처럼 보여 낙관적 업데이트를 적용했지만, 실패 때 현재 숫자에서 하나 빼는 방식은 여러 번 클릭하면 틀어졌다.
변경 전 스냅샷을 저장했다
요청 시작 순간의 상태를 복사하고 성공하면 서버 응답을 확정값으로 쓴다. 실패하면 계산하지 않고 스냅샷을 복원한다.
async function toggleLike() {
const previous = { liked, count }
setLiked(!liked)
setCount(count + (liked ? -1 : 1))
try {
const result = await fetch('/api/like', { method: 'POST' })
if (!result.ok) throw new Error('like request failed')
const serverState = await result.json()
setLiked(serverState.liked)
setCount(serverState.count)
} catch {
setLiked(previous.liked)
setCount(previous.count)
setError('저장하지 못했습니다. 잠시 후 다시 시도해 주세요.')
}
}
중복 요청을 막기 위해 pending 동안 버튼을 비활성화했다. 요청 순서가 뒤섞이는 UI라면 요청 ID나 서버 버전도 필요하다.
놓쳤던 테스트
성공만 테스트한 뒤 실패를 재현했다. 첫 요청을 지연 후 실패시키기, 실패 메시지 중 재클릭하기, 서버가 예상과 다른 count를 반환하기를 확인했다. 기준은 원래 값이 아니라 실패 직전 스냅샷과 일치하는가였다.
적용 전 점검
- 롤백에 현재 상태를 계산해 쓰지 않는다.
- 성공 시 서버 응답을 최종 기준으로 삼는다.
- 중복 클릭과 순서 뒤바뀜을 처리한다.
- 실패 사실을 사용자에게 알린다.
화면을 빠르게 만드는 것보다 실패했을 때 믿을 만하게 돌아오는 것이 더 중요한 기준이었다.