Skip to content

Refactor: Seal useRepositorySearch API — replace raw setters with semantic actions #143

@ryota-murakami

Description

@ryota-murakami

Background

Code quality analysis (2026-02-20) identified useRepositorySearch as a leaky abstraction — it exposes raw state setters that break encapsulation.

Current State

src/hooks/board/useRepositorySearch.ts returns 11 values, of which 6 are raw setters:

return {
  searchQuery, setSearchQuery,       // raw setter
  selectedRepos, setSelectedRepos,   // raw setter
  isAdding, setIsAdding,             // raw setter
  addError, setAddError,             // raw setter
  deferredSearchQuery,
  toggleRepoSelection,               // ✅ semantic
  removeSelectedRepo,                // ✅ semantic
}

Problem: Consumers can set arbitrary intermediate states (e.g., setIsAdding(true) without actually adding). This couples consumers to internal implementation details.

React official guidance: "A custom hook makes the data flow explicit. You feed the input in and you get the output out." Raw setter exposure violates this principle.

Proposed Change

Replace raw setters with semantic action functions:

return {
  searchQuery, updateSearch,          // setSearchQuery → updateSearch
  deferredSearchQuery,
  selectedRepos, toggleRepoSelection, removeSelectedRepo, clearSelection,
  isAdding, startAdding, finishAdding,
  addError, clearError,
}

Acceptance Criteria

  • No raw setState functions in the return type
  • All returned functions wrapped in useCallback
  • Consumer code (AddRepositoryCombobox.tsx) updated to use new API
  • TypeScript interfaces updated (UseRepositorySearchReturn)
  • No behavior changes — pure API improvement
  • All existing tests pass

Impact

  • Improved encapsulation — consumers cannot put hook in invalid states
  • Clearer API surface — each function describes what it does, not how

Metadata

Metadata

Assignees

No one assigned

    Labels

    refactoringCode quality and structural improvements

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions