← 모든 프로젝트
HASHI 팀 공개 자료의 식당 상세·예약 입력·예약 요청 완료 화면TEAM PRESENTATION · HASHI

HASHI · RESERVATION

예약 데이터의 캐시와 중복 요청 처리

예약 응답에 없는 데이터를 캐시에 추측해 넣지 않도록 갱신 기준을 정했습니다. 재렌더 전 연속 클릭으로 생기는 중복 요청도 동기 잠금으로 처리했습니다.

ReactTanStack QueryTesting Library
담당 범위
예약·포인트 API 연동 · 캐시 정책 · 중복 요청 회귀 처리
기간·맥락
2026.07 주요 PR / 프로젝트 2026.06–현재
현재 단계
PR 병합 / 클라이언트 회귀 검증 기록
이 사례의 핵심 변화

불완전한 응답은 재조회하고, 재렌더 전 연속 클릭은 동기 잠금으로 차단

01

배경: 예약 생성은 포인트와 다음 화면도 바꾼다

HASHI는 한국인 여행객을 위한 일본 맛집 큐레이션·예약 요청 서비스입니다. 일반 예약과 ‘어디든’ 예약 생성, 포인트 사용 API를 연결하면서 성공 응답 이후의 데이터 흐름을 함께 다뤘습니다.

사용자는 예약을 만들고 상세 화면으로 이동합니다. 동시에 포인트 잔액도 달라질 수 있습니다. 예약 요청만 성공시키고 끝내면 화면마다 다른 시점의 데이터를 보여줄 수 있는 조건이었습니다.

02

문제 분석: 응답에 없는 최신 값을 채울 수는 없다

예약 생성 응답에는 예약 ID가 있지만, 완전한 예약 상세 객체나 최신 포인트 잔액이 보장되지 않았습니다. 응답을 그대로 상세 캐시에 넣으면 부족한 필드를 추측해야 하고, 기존 값을 복사하면 오래된 정보가 새 결과처럼 보일 수 있습니다.

응답 계약과 화면에서 필요한 데이터
데이터생성 응답에서 확보처리
예약 ID상세 이동에 사용할 ID해당 ID의 상세 경로로 이동
완전한 예약 상세보장되지 않음부분 응답으로 상세 캐시를 만들지 않음
최신 포인트 잔액보장되지 않음포인트 조회 캐시를 무효화해 재조회
03

선택 기준: 직접 갱신과 재조회는 조건이 다르다

이 흐름에서는 불완전한 상세 객체를 작성하지 않고, 현재 조회하는 포인트 잔액을 무효화해 서버의 최신 값을 다시 받도록 구현했습니다. 성공 후 다른 화면으로 이동한다는 조건도 함께 봤습니다.

실제 API 연동 문서에 반영한 선택 기준
조건선택판단 이유
같은 화면에서 완전한 최신 객체를 받음setQueryData응답이 화면에서 필요한 정보를 충족
부분 응답·화면 이동·집계 변화invalidateQueries서버의 최신 조회 결과가 필요
상세 즉시 반영 + 관련 목록·집계 갱신두 방식 조합상세와 목록이 요구하는 갱신 시점이 다름

재조회 방식은 추가 요청과 대기 상태를 수반합니다. 이 사례에서는 응답 계약이 충분하지 않으므로, 클라이언트가 상세를 구성하는 것보다 서버 조회를 기준으로 삼는 쪽이 맞았습니다. 모든 mutation에 같은 방법을 쓰도록 일반화하지 않았습니다.

04

데이터 흐름: 예약 성공 이후의 책임 분리

  1. 예약 요청입력과 사용할 포인트 전달
  2. 성공 응답예약 ID 수신
  3. 포인트 갱신관련 query 무효화
  4. 상세로 이동서버 조회를 기준으로 상세 표시
예약·포인트 연동 구현을 설명한 흐름

예약 ID는 다음 화면을 식별하는 데 사용하고, 포인트 잔액은 해당 조회가 최신 데이터를 가져오게 했습니다. 한 응답으로 해결할 수 없는 데이터까지 생성 결과에 억지로 합치지 않았습니다.

05

별도 발견: 버튼이 비활성화되기 전의 두 번 클릭

같은 작업의 회귀 테스트에서는 확인 버튼을 대기 없이 연속 클릭했을 때 생성 함수가 두 번 호출됐습니다. mutation.isPending은 재렌더 뒤에 반영되므로 두 handler가 모두 이전 false 값을 읽을 수 있었습니다.

  1. 첫 클릭isPending=false를 읽음
  2. 요청 시작재렌더는 아직 반영 전
  3. 두 번째 클릭이전 false를 읽고 다시 요청
수정 전의 재현 조건

handler 진입 즉시 useRef 잠금을 잡고 onSettled에서 해제하도록 수정했습니다. 버튼 비활성화는 진행 상태를 표현하고, 동기 잠금은 재렌더 이전의 진입을 막는 역할입니다.

동작 설명용 의사코드 — 실제 소스 그대로가 아닌 책임 요약
예약 확인:
  잠금이 이미 잡혀 있으면 종료
  동기 잠금 설정
  예약 mutation 실행

요청 종료(onSettled):
  잠금 해제
  실패한 경우 사용자가 다시 시도할 수 있음
06

후속 작업: 발견한 기준을 문서와 리뷰에 남기기

캐시 선택표를 API 연동 스킬, 데이터 계층 문서, 작업 절차에 함께 반영했습니다. 다음 작업에서 완전한 응답인지, 화면이 이동하는지, 목록이나 집계가 함께 달라지는지를 확인할 수 있게 했습니다.

다른 PR 리뷰에서도 예약 취소의 재렌더 전 중복 요청과 리뷰 작성 후 식당 평점·개수 캐시 갱신 누락을 짚었습니다. 동료에게 재현 조건과 수정안을 제시한 범위이며, 후속 구현 전체를 제 기여로 포함하지 않습니다.

07

검증: 성공 경로보다 경계 조건을 함께 확인

PR에 기록된 클라이언트 회귀 검증
조건확인한 동작검증 범위
같은 tick에서 연속 확인예약 생성 호출 1회수정 전 2회 호출 재현 후 비교
요청 실패 뒤 재시도잠금 해제 후 다시 실행 가능실패 복구
요청 진행 중 취소·Escape다이얼로그 닫기 제한클라이언트 상호작용
예약 성공포인트 캐시 갱신 처리연동 코드·당시 PR 기록

위 결과는 당시 PR의 테스트·검증 보고입니다. 이번 포트폴리오 편집에서 운영 서버를 호출하거나 같은 테스트를 다시 실행한 것은 아닙니다.

08

이 사례의 기준: 서버가 준 정보만큼만 확정하기

예약 생성에서는 응답이 보장하는 정보의 범위를, 중복 요청에서는 React 상태가 반영되는 시점을 각각 확인했습니다. 데이터의 완전성과 상태의 반영 시점을 구체적으로 나누는 것이 두 문제를 해결한 공통 기준입니다.

문서와 스킬에 반영한 기준이 팀 전체의 시간 절감으로 이어졌는지는 별도 측정이 없습니다. 여기서 확인되는 결과는 동작 수정, 회귀 조건, 후속 작업에서 참조할 판단 기준입니다.

↗

공개 근거·관련 링크

다음 프로젝트반복 수정하던 결과 화면의 공통 구조 정리 ↗