Skip to content

refactor: 공통 useBulkSelection 훅 추출 (PR-E)#74

Merged
bbbang105 merged 1 commit into
devfrom
feature/pr-e-component-split
Apr 21, 2026
Merged

refactor: 공통 useBulkSelection 훅 추출 (PR-E)#74
bbbang105 merged 1 commit into
devfrom
feature/pr-e-component-split

Conversation

@bbbang105
Copy link
Copy Markdown
Owner

Summary

feed-list (921 줄)과 youtube-feed (1201 줄) 둘 다 같은 bulk-selection 패턴(selectMode + Set + toggle / select all / exit)을 각자 손으로 관리 중이었음. 공통 훅으로 추출하고 양쪽 적용.

전체 컴포넌트 분리(useXxxState + Section 컴포넌트)는 invasive 리팩터링이라 시각 검증이 따로 필요. PR-E 범위에는 포함하지 않고 follow-up 으로 남김.

변경

신규 `hooks/use-bulk-selection.ts`

API: `selectMode`, `selectedIds`, `selectedCount`, `toggle`, `deselect`, `selectAll`, `clear`, `toggleSelectAll(ids)`, `enterSelectMode`, `exitSelectMode`, `toggleSelectMode`

핵심 불변: `exitSelectMode` / `toggleSelectMode` (leave) 는 selection 까지 초기화해서 re-entry 시 stale id 가 다시 나타나는 버그 방지.

신규 테스트 `tests/use-bulk-selection.test.ts`

  • toggle in/out
  • toggleSelectAll 플립 (full → clear / partial → all)
  • deselect (present / absent)
  • exit clears selection
  • toggleSelectMode: enter keeps, leave clears

`feed-list.tsx`

  • 로컬 `toggleSelect` / `toggleSelectAll` / `exitSelectMode` + `selectMode` / `selectedIds` useState 전부 제거
  • 훅에서 받아 기존 call-site 그대로 사용

`youtube-feed.tsx`

  • 동일. 인라인 Set 토글 4곳이 한 줄 호출로 정리.

불변

  • 선택 모드 UX / 체크박스 렌더 / bulk delete, mark_unread, summarize 핸들러 전부 동일
  • URL 필터 변경 시 select mode 자동 종료 동일
  • 259 tests (기존 254 + 새 5), typecheck / lint 통과

Test plan

  • 피드 선택 모드: 진입 → 카드 토글 → Select all / Clear all → 일괄 삭제 / 읽음 되돌리기
  • 유튜브 Feed 탭 선택 모드: 동일
  • 유튜브 Collect 탭 선택 모드: 영상 요약 실행
  • URL 필터 변경 시 선택 모드 자동 종료
  • 선택 모드 재진입 시 이전 선택 리셋

이번 PR 범위 외 (Follow-up)

  • feed-list / youtube-feed 컴포넌트 완전 분리 (useFeedListState + useYoutubeFeedState 훅 + Filter/List/EmptyState 서브 컴포넌트) — invasive, 별도 PR로.
  • 추가 공유 가능 후보: `usePinnedItems`, `useFeedMeta`

🤖 Generated with Claude Code

feed-list.tsx (921 lines) 와 youtube-feed.tsx (1201 lines) 둘 다
똑같은 bulk-selection 패턴을 각자 손으로 관리하고 있었음:
- selectMode + Set<string> selectedIds
- 단일 아이템 toggle
- Select all / Clear all
- exit select mode 시 selection 초기화

이 셋업을 `useBulkSelection` 훅으로 추출하고 양쪽에 적용. 전체 컴포넌트
분리(useXxxState + Section 컴포넌트)는 invasive 리팩터링이라 시각 검증
요하는 별도 follow-up 으로 남김.

## 변경
- 신규: `packages/web/src/hooks/use-bulk-selection.ts`
  - API: `selectMode`, `selectedIds`, `selectedCount`, `toggle`, `deselect`,
    `selectAll`, `clear`, `toggleSelectAll(ids)`, `enterSelectMode`,
    `exitSelectMode`, `toggleSelectMode`
  - 불변: exitSelectMode / toggleSelectMode leave 는 selection 까지 초기화
    (stale id leak 방지)
- 신규: `packages/web/src/__tests__/use-bulk-selection.test.ts`
  - toggle / deselect / toggleSelectAll 플립 / exit clear / mode flip 5 tests
- `feed-list.tsx`: local toggleSelect / toggleSelectAll / exitSelectMode +
  selectMode/selectedIds useState 전부 제거 → 훅에서 받아 그대로 사용
- `youtube-feed.tsx`: 동일 (set-based 토글 인라인 구현 4곳 훅 한 줄 호출로)

## 불변
- 선택 모드 진입/나감 UX, 체크박스 렌더, bulk delete / mark_unread /
  summarize 핸들러 동작 모두 동일
- URL 필터 변경 시 select mode 자동 종료 동일 (exitSelectMode() 한 번 호출)
- 259 tests 통과 (기존 254 + 새 5), typecheck / lint 통과

## Follow-up (이번 PR 범위 외)
- feed-list / youtube-feed 컴포넌트 완전 분리 (useXxxState + Section 컴포넌트)
  는 invasive, 시각 검증이 따로 필요. 별도 PR 로 진행.
- 추가 공유 가능 패턴: pinned items fetch, meta (sources/categories/favorites)
  초기 로드. 필요 시 usePinnedItems / useFeedMeta 로 추출 가능.

Co-Authored-By: Claude <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 21, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
forme Ready Ready Preview, Comment Apr 21, 2026 5:44am

@bbbang105 bbbang105 added the ✅ test 테스트 코드 label Apr 21, 2026
@bbbang105 bbbang105 added the 🔄 refactor 코드 리팩토링 label Apr 21, 2026
@bbbang105 bbbang105 merged commit 9bfcc87 into dev Apr 21, 2026
8 checks passed
@bbbang105 bbbang105 deleted the feature/pr-e-component-split branch April 21, 2026 06:05
bbbang105 added a commit that referenced this pull request Apr 21, 2026
PR #73 (SavedItemBase) + #74 (useBulkSelection) 머지 후속. 다음 세션에서
이 공통 프리미티브 위치를 바로 찾을 수 있도록 테이블에 등록.

Co-Authored-By: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🔄 refactor 코드 리팩토링 ✅ test 테스트 코드

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant