-
Notifications
You must be signed in to change notification settings - Fork 0
[FIX] 버튼 "따닥"으로 인한 중복 호출로 시간표가 여러 개 생기는 문제 해결 #321
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Conversation
WalkthroughAPI 중복 요청(따닥 문제) 방지를 위해, 테이블 생성 및 수정 관련 mutation에 대해 중복 호출을 차단하는 커스텀 훅( Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant UI
participant usePreventDuplicateMutation
participant API
User->>UI: 버튼 클릭 (테이블 생성/수정)
UI->>usePreventDuplicateMutation: mutate() 호출
alt 이미 mutation 진행 중
usePreventDuplicateMutation-->>UI: 중복 호출 무시, 경고 로그
else mutation 진행 중 아님
usePreventDuplicateMutation->>API: API 요청 전송
API-->>usePreventDuplicateMutation: 응답 반환
usePreventDuplicateMutation-->>UI: onSuccess/onError/onSettled 콜백 실행
end
Suggested labels
Suggested reviewers
Poem
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
npm error Exit handler never called! ✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
vite.config.ts (1)
18-20
: 포트 번호 하드코딩 대신 환경변수 사용 권장개발 환경마다 이미 3000 포트를 점유하고 있을 수 있어 충돌 위험이 있습니다.
loadEnv
로 환경변수를 불러오고 있으니, 동일한 방식으로 포트도 주입하면 유연성이 높아집니다.- port: 3000, + // 기본값 3000, 필요 시 VITE_DEV_SERVER_PORT 환경변수로 오버라이드 + port: Number(env.VITE_DEV_SERVER_PORT) || 3000,
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
src/apis/axiosInstance.ts
(1 hunks)src/hooks/mutations/useAddDebateTable.ts
(1 hunks)src/hooks/mutations/usePreventDuplicateMutation.ts
(1 hunks)src/hooks/mutations/usePutDebateTable.ts
(1 hunks)src/page/TableComposition/TableComposition.tsx
(3 hunks)src/page/TableComposition/components/TimeBoxStep/TimeBoxStep.tsx
(3 hunks)src/page/TableComposition/hook/useTableFrom.tsx
(2 hunks)vite.config.ts
(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (3)
src/hooks/mutations/useAddDebateTable.ts (1)
src/hooks/mutations/usePreventDuplicateMutation.ts (1)
usePreventDuplicateMutation
(8-47)
src/page/TableComposition/TableComposition.tsx (1)
src/repositories/ApiDebateTableRepository.ts (2)
editTable
(26-31)addTable
(21-24)
src/hooks/mutations/usePutDebateTable.ts (3)
src/type/type.ts (1)
DebateTableData
(49-52)src/hooks/mutations/usePreventDuplicateMutation.ts (1)
usePreventDuplicateMutation
(8-47)src/apis/responses/debateTable.ts (1)
PutDebateTableResponseType
(9-11)
🔇 Additional comments (21)
src/apis/axiosInstance.ts (1)
10-10
: 개발 환경 문제 해결을 위한 좋은 변경사항입니다.baseURL 설정을 단순화하여 개발 환경에서 undefined URL 문제를 해결하는 좋은 접근법입니다. 이제 모든 환경에서 일관되게 환경 변수를 사용하게 됩니다.
src/hooks/mutations/useAddDebateTable.ts (2)
4-4
: 중복 호출 방지를 위한 적절한 import입니다.새로운
usePreventDuplicateMutation
훅을 import하여 버튼 따닥 문제를 해결하는 좋은 접근법입니다.
7-15
: LGTM! 중복 mutation 방지 로직이 잘 적용되었습니다.
useMutation
을usePreventDuplicateMutation
으로 교체하여 중복 API 호출을 방지하는 핵심 기능이 잘 구현되었습니다. 기존 인터페이스를 유지하면서 중복 방지 기능을 추가한 것이 좋습니다.src/hooks/mutations/usePutDebateTable.ts (2)
4-4
: 중복 호출 방지를 위한 적절한 import입니다.
usePreventDuplicateMutation
훅을 import하여 테이블 수정 시에도 중복 호출을 방지할 수 있도록 했습니다.
11-26
: LGTM! 타입 안전성과 중복 방지 기능이 잘 구현되었습니다.
usePreventDuplicateMutation
으로 교체하면서 제네릭 타입 매개변수를 올바르게 유지했고, 기존 mutation 로직과 콜백을 그대로 보존했습니다. 중복 호출 방지 기능이 깔끔하게 적용되었습니다.src/page/TableComposition/TableComposition.tsx (3)
42-50
: LGTM! 로딩 상태 관리와 함수명 개선이 잘 적용되었습니다.
useTableFrom
훅에서 새로운 로딩 상태 플래그(isAddingTable
,isModifyingTable
)를 추가하고 함수명을 camelCase로 통일한 것이 좋습니다. 이를 통해 UI 레벨에서 중복 호출을 방지할 수 있습니다.
62-65
: 함수 호출이 새로운 네이밍에 맞게 잘 업데이트되었습니다.
AddTable
과EditTable
에서addTable
과editTable
로 일관된 camelCase 네이밍을 사용하도록 변경한 것이 좋습니다.
87-87
: UI 레벨 중복 방지를 위한 적절한 prop 전달입니다.현재 모드에 따라 적절한 로딩 상태를
isSubmitting
prop으로 전달하여 버튼 비활성화 기능을 구현한 것이 좋습니다. 이는 PR의 핵심 목표인 "따닥" 문제 해결에 기여합니다.src/page/TableComposition/components/TimeBoxStep/TimeBoxStep.tsx (3)
18-18
: UI 상태 관리를 위한 적절한 prop 추가입니다.
isSubmitting
prop을 추가하여 제출 상태에 따른 버튼 비활성화 기능을 구현할 수 있도록 했습니다.
28-28
: 기본값 설정으로 하위 호환성을 보장한 좋은 구현입니다.
isSubmitting
의 기본값을false
로 설정하여 기존 코드와의 호환성을 유지하면서 새로운 기능을 추가했습니다.
129-129
: LGTM! 버튼 비활성화 로직이 완벽하게 구현되었습니다.기존 조건(
!isAbledSummitButton
)과 새로운 제출 상태 조건(isSubmitting
)을 모두 고려하여 버튼을 비활성화하는 로직이 잘 구현되었습니다. 이는 PR의 핵심 목표인 중복 호출 방지의 UI 레벨 구현을 완성합니다.src/hooks/mutations/usePreventDuplicateMutation.ts (5)
1-6
: import 구문이 올바르게 구성되어 있습니다.필요한 React 훅들과 react-query의 타입들이 적절히 import되어 있습니다.
8-15
: 제네릭 타입 정의가 잘 구성되어 있습니다.
useMutation
과 동일한 제네릭 타입 매개변수를 사용하여 타입 안정성을 보장하고 있습니다.
16-26
: 플래그 초기화 및 onSettled 콜백 구현이 적절합니다.
useRef
를 사용하여 렌더링에 의존하지 않는 상태 관리를 하고 있으며, 기존onSettled
콜백을 보존하면서 플래그를 재설정하는 로직이 올바릅니다.
30-44
: 중복 호출 방지 로직이 잘 구현되어 있습니다.
useCallback
을 사용하여 함수 참조를 안정화하고, 플래그를 통해 중복 호출을 효과적으로 차단하고 있습니다. 콘솔 경고 메시지도 적절합니다.
46-46
: mutation 결과 반환이 올바르게 구현되어 있습니다.기존 mutation의 모든 속성을 spread하면서
mutate
함수만 중복 방지 버전으로 오버라이드하는 방식이 적절합니다.src/page/TableComposition/hook/useTableFrom.tsx (5)
83-88
: mutation 훅 사용법이 올바르게 업데이트되었습니다.
isPending
상태를isAddingTable
로 추출하고, 콜백 함수를 명시적으로 첫 번째 인자로 전달하는 방식이 적절합니다.
90-98
: 수정 mutation 훅 사용법이 적절합니다.게스트 플로우를 고려한 네비게이션 로직이 보존되어 있으며,
isPending
상태를isModifyingTable
로 추출하는 것이 적절합니다.
100-105
: 함수명 변경이 일관성을 개선했습니다.
AddTable
에서addTable
로 변경하여 camelCase 명명 규칙을 따르도록 개선되었습니다.
107-113
: 수정 함수명도 일관성 있게 변경되었습니다.
EditTable
에서editTable
로 변경하여 명명 규칙의 일관성을 유지하고 있습니다.
119-122
: 로딩 상태 노출이 UI 반응성을 향상시킵니다.
isAddingTable
과isModifyingTable
상태를 반환하여 상위 컴포넌트에서 로딩 상태를 처리할 수 있도록 하는 것이 좋은 개선입니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
확인했습니다! 변경 사항이 간결하고 핵심에만 집중해주셔서 보기가 편했어요. 반드시 개선이 필요하다 싶은 사항은 없어서 승인을 남깁니다. 고생하셨어요!
mutateOptions?: Parameters<typeof mutation.mutate>[1], | ||
) => { | ||
if (isMutatingRef.current) { | ||
console.warn('이미 요청이 처리 중 입니다.'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
대안: 콘솔에 알리지 말고 경고 창 띄우기
콘솔은 보통 개발자 아니면 보지 않을 것 같아서, 콘솔보다는 alert()
함수 등으로 간단하게나마 사용자에게 중복 요청임을 알리는 게 좋을 것 같아요.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
대안: 주석 추가
코드는 간결하나 - 특히나 제가 TanStack Query에 대한 배경 지식이 적기도 하고 - 주석이 없어서 어떤 과정을 거쳐 동작하는지 직관적으로 파악하기가 어려웠습니다. 앞으로 PR 작성하시면서 여유가 조금 있으시다면... 핵심 코드에 간단한 주석 한 줄 정도만 달아주세요! 흐름을 이해하고 썬데이가 코드를 작성한 의도를 파악하는 게 훨씬 수월할 것 같습니다.
추가로 하나 더 적자면, src/main.tsx의 코드 10~17번 줄까지 지워야 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
구현하느라 고생하셨습니다. useMutate를 래핑하는 방식에서 좋은 인사이트를 얻을 수 있었습니다. 덕분에 useMutate에 대해서 조금 더 잘알게 되는 계기가 아니었을까 싶습니다. 이번에 타입을 비교하면서 실제 구현해주신 부분과 차이가 있어서 궁금증으로 코멘트를 남깁니다. 한번확인해주세요!
|
||
export function usePreventDuplicateMutation< | ||
TData = unknown, | ||
TError = Error, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
실제 useMutation함수에서 Error가 아니라 DefaultError를 기본 타입으로 사용하고 있는데 Error타입을 선언하신 이유가 있을까요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚩 연관 이슈
closed #258
📝 작업 내용
1️⃣ npm run dev 실행 안 되는 문제 해결
그동안 dev 실행이 안돼서 매번 build하고 preview로 확인했다고 하셔서 수정했습니다!
2️⃣ 버튼 "따닥"으로 인한 중복 호출 문제 해결
📌 문제 정의
간헐적으로 시간표 생성이나 수정 시 버튼을 여러 번 클릭하는 경우 여러 개 생성되는 문제가 발생했습니다.

참고로 제가 버튼 클릭이 느린지 생성이 하나만 돼서 커찬한테 부탁했더니 .., 이런 시간표를 생성했네요 ^^;;
해당 호출 당시 서버 로그

이렇게 짧은 시간에 요청이 두 번 가는 것을 확인할 수 있었습니다. 하나의 API 요청이 처리되기 전에 동일한 API 요청이 바로 들어와 두 개가 생성이 되는 것이 원인이었습니다.
✨ 해결 과정
두 가지 방법을 통해 UI 레벨에서 중복 클릭을 방지하고, 뮤테이션 로직 자체의 중복 실행을 방지하도록 구현했습니다.
1. useMutation의 isPending 상태를 활용한 버튼 클릭 disabled 처리
사용자가 뮤테이션이 진행 중일 때 버튼을 클릭하지 못하게 하여 중복 호출을 방지할 수 있습니다.
하지만 UI 레벨의 제어라서 개발자 도구에서 true로 변경하면 클릭할 수 있고, isPending 상태가 true로 변경되고 UI가 다시 렌더링되기까지 지연이 발생할 수 있습니다. 이때 버튼에 여러 번 클릭 이벤트가 발생할 수 있습니다.
2. usePreventDuplicateMutation
렌더링과 독립적으로 뮤테이션의 진행 여부를 추적하고자 useRef를 사용했습니다.
동작 원리는 다음과 같습니다.
또한 내부에서 useMutation을 실행하여 기존에 useMutate를 사용하는 사용처에서 별도의 코드 변경 없이 usePreventDuplicateMutation으로 감싸서 사용할 수 있습니다.
사용 예시
🏞️ 스크린샷 (선택)
아래는 버튼 클릭 시 mutation을 호출을 세 번 실행하도록 테스트한 결과입니다.
첫 번째 요청은 정상적으로 처리되어 API 호출이 되고, 두 번째 요청과 세 번째 요청은 바로 막히고 console이 찍히는 것을 확인할 수 있습니다.
default.mp4
🗣️ 리뷰 요구사항 (선택)
ㅎㅎㅎ 디베이트 합류 후 첫 PR이네요 두근 두근 !!!!!!!!!!!!!!! 잘 부탁드립니다 🫡✨
Summary by CodeRabbit
New Features
Refactor
Chores