
예약내역 페이지에서 사용자는 더 이상 필요하지 않은 예약을 직접 취소할 수 있다.
이를 위해 확인 모달(WarningModal)을 띄운 뒤, 취소 API를 호출하고 UI에 바로 반영하는 흐름을 구현하였다.
이 글에서는 해당 기능의 흐름과 상태 관리 구조를 상세히 설명한다.
const [reservations, setReservations] = useState<MyReservationType[]>([]);
- 예약 목록은 상태로 관리되며,
map을 통해 특정 예약의 상태만 업데이트할 수 있다.
setReservations((prev) => prev.map((r) => r.id === reservationId ? { ...r, status: "canceled" } : r ) );
- 이 방식은 불필요한 API 재요청 없이 UI를 즉시 갱신할 수 있는 장점이 있다.
1️⃣ 예약 카드에서 취소 버튼 클릭
onCancelReservation={() => handleCancelReservation(reservation.id)}
MyReservationCard컴포넌트에서 예약 객체를 기반으로 취소 버튼을 렌더링한다.- 버튼 클릭 시 예약 ID를 인자로 전달하여
handleCancelReservation이 실행된다.
2️⃣
WarningModal확인 모달 표시const handleCancelReservation = (id: number) => { overlay.overlay( <WarningModal message="예약을 취소하시겠어요?" confirmText="취소하기" onConfirm={() => { handleCancelReservationApi(id); overlay.close(); }} /> ); };
useOverlay훅을 사용해 경고 모달을 띄운다.- 사용자가 확인 버튼을 누르면 실제 API 호출이 이뤄지고, 오버레이가 닫힌다.
3️⃣ 예약 상태 변경 API 호출
const handleCancelReservationApi = async (reservationId: number) => { try { await reservationService.patchMyReservations({ reservationId, payload: { status: "canceled" }, }); // setReservations((prev) => prev.map((r) => r.id === reservationId ? { ...r, status: "canceled" } : r ) ); } catch (error) { console.error("예약 취소 실패:", error); } };
reservationId를 기준으로 서버에 상태 변경 요청을 보낸다.- 응답이 성공적으로 오면 클라이언트 상태도 직접 갱신한다.
- 오류가 발생할 경우 콘솔에 에러를 출력한다.
🖥️ 결과물
- 예약 취소는 버튼 클릭 → 확인 모달 → API 호출 → 상태 갱신 순으로 이루어진다.
useOverlay를 활용하여 사용자 경험을 해치지 않으면서도 안전하게 확인 절차를 넣을 수 있었다.- 상태 갱신은 기존 배열을 복사하고 일부만 변경하는 방식으로 처리하였다.
경고 모달과 API 후 상태 반영까지 하나의 흐름으로 유기적으로 설계한 것이 핵심이다