Skip to content

[FIX] 버튼 중복 입력 및 알림창 터치 관통 방지#66

Merged
kbh0218 merged 5 commits into
devfrom
fix/#56-prevent-duplicate-taps-alert-touch-through
May 29, 2026
Merged

[FIX] 버튼 중복 입력 및 알림창 터치 관통 방지#66
kbh0218 merged 5 commits into
devfrom
fix/#56-prevent-duplicate-taps-alert-touch-through

Conversation

@kbh0218

@kbh0218 kbh0218 commented May 25, 2026

Copy link
Copy Markdown
Contributor

Closes #56

개요

앱 전반에서 버튼을 빠르게 여러 번 누를 때 동일한 액션이 중복 실행되는 문제를 방지했습니다.

기존에는 저장, 삭제, 수정, 폴더 생성/수정/삭제, 화면 이동 버튼 등을 빠르게 연속 터치하면 동일한 API 요청이나 네비게이션이 여러 번 실행될 수 있었습니다. 예를 들어 링크 저장 버튼을 연속으로 누르면 저장 요청이 중복으로 발생할 수 있고, 삭제 확인창의 삭제 버튼을 빠르게 누르면 동일 삭제 요청이 반복 실행될 여지가 있었습니다. 화면 이동 버튼 역시 짧은 시간 안에 여러 번 입력되면 같은 화면이 중복으로 push될 수 있는 구조였습니다.

이번 작업에서는 이런 문제를 개별 화면에서만 막는 방식이 아니라, 공통 버튼과 주요 액션 컴포넌트에 재사용 가능한 press guard를 적용하는 방식으로 정리했습니다. 버튼을 한 번 누른 직후 짧은 시간 동안 추가 입력을 무시하고, 비동기 요청을 반환하는 액션은 요청이 끝날 때까지 같은 액션이 다시 실행되지 않도록 했습니다. 여기에 저장, 삭제, 수정, 폴더 생성처럼 실제 API 요청을 발생시키는 흐름에는 별도의 in-flight 상태를 함께 적용해 렌더링 타이밍 사이에 발생할 수 있는 재진입도 방지했습니다.

또한 Alert.alert 확인창이 표시된 상태에서 뒤쪽 화면의 버튼이 함께 눌리지 않도록 보완했습니다. Alert 표시 중에는 앱 루트에 투명한 터치 차단 레이어를 올려 뒤 화면으로 터치가 관통하지 않게 하고, 확인창의 확인/삭제/취소 버튼 역시 빠르게 연속으로 눌러도 동일 콜백이 반복 실행되지 않도록 showAlert 래퍼를 통해 관리했습니다.

이 과정에서 검사 시작 버튼처럼 화면 이동 직후 잠금 상태가 남을 수 있는 케이스도 함께 확인했습니다. 검사 화면으로 이동한 뒤 뒤로가기로 입력 화면에 돌아왔을 때 버튼이 계속 비활성화되지 않도록, 화면이 다시 포커스될 때 네비게이션 잠금을 해제하도록 수정했습니다.

주요 구현 내용

  • 공통 중복 입력 방지 유틸 utils/press-guard.ts 추가
  • 공통 Alert 래퍼 utils/guarded-alert.ts 추가
  • Alert 표시 중 뒤 화면 터치 차단용 PressBlocker 추가
  • 루트 layout에 PressBlocker 연결
  • 공통 버튼 컴포넌트에 useGuardedPress 적용
  • Button, AppIcon, ActionIconButton, AddFolderButton, ScanButton 중복 입력 차단
  • 카드, 칩, 메뉴, 모달 버튼 등 주요 공통 액션 컴포넌트 중복 입력 차단
  • 저장 링크 저장 버튼 연속 입력 방지
  • 링크 삭제 확인창 및 삭제 요청 중복 실행 방지
  • 링크 제목 수정 저장 버튼 연속 입력 방지
  • 폴더 생성, 폴더명 수정, 폴더 삭제 요청 중복 실행 방지
  • 폴더 URL 추가/제외 요청 중복 실행 방지
  • 화면 이동 버튼 빠른 연속 터치 시 중복 push 방지
  • 검사 시작 후 뒤로 돌아왔을 때 버튼 잠금이 유지되는 문제 수정
  • Alert.alert 직접 호출을 showAlert 기반 흐름으로 정리

파일별 역할

  • utils/press-guard.ts: 버튼/Pressable 액션의 짧은 연속 입력 및 in-flight 중복 실행 차단
  • utils/guarded-alert.ts: Alert 표시 중 전역 터치 차단 상태를 시작/해제하고 Alert 버튼 중복 실행 방지
  • components/ui/press-blocker.tsx: Alert 표시 중 뒤 화면 터치를 막는 투명 차단 레이어
  • app/_layout.tsx: 앱 루트에 PressBlocker 연결
  • components/ui/button.tsx: 공통 Button의 disabled/loading 상태 및 press guard 적용
  • components/ui/app-icon.tsx: 공통 아이콘 버튼 press guard 적용
  • components/ui/action-icon-button.tsx: 삭제/지우기 액션 버튼 press guard 적용
  • components/ui/add-folder-button.tsx: 폴더 추가 버튼 press guard 적용
  • components/ui/scan-button.tsx: 검사 시작 버튼 press guard 적용
  • components/ui/card-link.tsx: 링크 카드, 북마크, 더보기 버튼 중복 입력 차단
  • components/ui/link-save-modal.tsx: 링크 저장 모달의 저장/취소 버튼 중복 입력 차단
  • components/ui/title-edit-modal.tsx: 제목 수정 모달의 저장/취소 버튼 중복 입력 차단
  • components/ui/folder-card.tsx: 폴더 카드 및 더보기 버튼 중복 입력 차단
  • components/ui/folder-context-menu.tsx: 컨텍스트 메뉴 항목 중복 실행 차단
  • app/(tabs)/(home)/scan-result.tsx: safe 결과 링크 저장 중복 요청 방지
  • app/(tabs)/(home)/scan-result-caution.tsx: caution 결과 링크 저장 중복 요청 방지
  • app/(tabs)/(home)/add-link.tsx: 검사 시작 중복 네비게이션 방지 및 뒤로가기 복귀 시 잠금 해제
  • app/(tabs)/(home)/index.tsx: 홈 최근 저장 링크 삭제/북마크/제목 수정 중복 실행 방지
  • app/(tabs)/(home)/saved-links.tsx: 저장 링크 목록 삭제/북마크/제목 수정 중복 실행 방지
  • app/(tabs)/(folder)/index.tsx: 폴더명 수정/삭제 중복 요청 방지
  • app/(tabs)/(folder)/folder-name.tsx: 폴더 생성 다음 화면 이동 중복 방지 및 복귀 시 잠금 해제
  • app/(tabs)/(folder)/folder-url-select.tsx: 폴더 생성 요청 중복 방지
  • app/(tabs)/(folder)/folder-add-url.tsx: 폴더 URL 추가 요청 중복 방지
  • app/(tabs)/(folder)/[id].tsx: 폴더에서 링크 제외 요청 중복 방지
  • app/(tabs)/(home)/settings.tsx: 로그아웃/회원탈퇴 확인창 및 요청 중복 실행 방지

해결한 이슈 목록

  • 앱 전반의 주요 버튼 중복 입력 발생 가능 지점 확인
  • 공통 Button 컴포넌트의 loading 또는 disabled 상태 중복 입력 차단 확인
  • AppIcon, ActionIconButton, AddFolderButton 등 공통 액션 버튼 중복 입력 차단 적용
  • 저장, 삭제, 수정, 이동 등 API 요청 또는 네비게이션을 발생시키는 버튼 우선 점검
  • 요청 처리 중인 버튼은 추가 입력이 발생하지 않도록 disabled 또는 in-flight 상태 적용
  • 저장 링크 저장 버튼 연속 클릭 시 중복 저장 요청 방지
  • 링크 삭제 버튼 연속 클릭 시 삭제 요청 중복 실행 방지
  • 링크 제목 수정 버튼 연속 클릭 시 수정 요청 중복 실행 방지
  • 폴더 생성, 폴더명 수정, 폴더 삭제 버튼 연속 클릭 시 중복 요청 방지
  • 화면 이동 버튼 빠른 연속 클릭 시 동일 화면 중복 push 방지
  • Alert.alert 확인창 표시 중 뒤쪽 화면 버튼 터치 차단
  • 확인창의 확인/삭제/취소 버튼 빠른 연속 클릭 시 동일 액션 중복 실행 방지
  • 검사 시작 후 뒤로가기 복귀 시 버튼 잠금이 해제되도록 처리
  • Android 에뮬레이터에서 빠른 연속 터치 수동 검증
  • 실제 휴대폰 preview 빌드에서 빠른 연속 터치 수동 검증

체크 사항

  • 커밋/코딩 컨벤션에 맞게 작성
  • 공통 버튼 컴포넌트에 중복 입력 방지 적용
  • 주요 API 요청 버튼에 in-flight 중복 실행 방지 적용
  • 주요 네비게이션 버튼에 연속 이동 방지 적용
  • Alert 표시 중 뒤 화면 터치 차단 처리
  • 기존 하단 탭 및 뒤로가기 동작은 별도 중복 차단 대상에서 제외

참고

북마크 버튼의 API 호출 간격 조정 또는 별도 디바운스 정책은 이슈 설명에 따라 이번 PR 범위에서 제외했습니다.

이번 PR에서는 버튼 중복 입력 방지와 Alert 표시 중 터치 관통 방지를 우선 처리했습니다.

@kbh0218 kbh0218 requested review from minsoo0506 and sunm2n May 25, 2026 18:19
@kbh0218 kbh0218 self-assigned this May 25, 2026
Comment thread app/(tabs)/(home)/notices.tsx Outdated
const handleRetry = useCallback(() => {
startLoadNotices();
}, [startLoadNotices]);
const guardedOpenNotice = useGuardedPress((id: number) =>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

notices.tsx - useCallback deps 누락 가능성

  const guardedOpenNotice = useGuardedPress((id: number) =>
    router.push({ ... }),
  );

  const renderNotice = useCallback(
    ({ item }) => <TouchableOpacity onPress={() => guardedOpenNotice?.(item.id)}
   />,
    [guardedOpenNotice],  // ← 올바르게 포함됨 ✓
  );

deps 포함은 맞는거 같습니다. 다만 guardedOpenNotice가 매 렌더마다 새로 생성되는 인라인
함수((id: number) => router.push(...))에 의존하므로, 렌더마다 useCallback이 무효화될 수 있습니다.
해당 함수를 컴포넌트 밖으로 분리하거나 useCallback으로 감싸면 최적화가 되지 않을까 합니다.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

피드백 감사합니다!

확인해보니 renderNotice의 dependency에 guardedOpenNotice를 포함한 것은 맞지만, useGuardedPress에 전달하는 handler가 인라인 함수라 매 렌더마다 새로 생성되고 있었습니다.

useGuardedPress 내부에서도 handler를 dependency로 사용하는 구조라, 결과적으로 guardedOpenNotice와 renderNotice가 불필요하게 재생성될 수 있다고 판단했습니다.

동작상의 문제는 아니지만 FlatList renderItem에 연결되는 콜백인 만큼, 가독성과 렌더 최적화를 위해 공지 상세 이동 handler를 useCallback으로 분리해 useGuardedPress에 전달하도록 수정하겠습니다.

@kbh0218 kbh0218 merged commit e1ee8aa into dev May 29, 2026
@kbh0218 kbh0218 deleted the fix/#56-prevent-duplicate-taps-alert-touch-through branch May 29, 2026 12:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FIX] 버튼 중복 입력 및 알림창 터치 관통 방지

2 participants