用途:在评估 React 组件或自定义 Hook 代码、设计实现新组件或 Hook、重构已有 Hook 或从组件中抽取 Hook 时使用。不适用于与 React 无关的普通函数/模块重构,也不适用于仅调用已验证的通用 Hook。
主要能力:提供一套判断标准,在创建或建议自定义 Hook 前先自问:该逻辑能否用不含 Hook 的普通函数或模块表达;Hook 的单一职责能否一句话说清;其依赖是否也是调用方应拥有的依赖;若删除并内联回调用方代码是否更清晰。
优先替代方案:计算、数据转换、校验、API 调用优先用普通函数/模块;单组件使用的事件处理或小型组合逻辑保留为组件局部逻辑;UI 职责过大或状态与控制流难追踪时,视为组件重设计候选。若结构性改动在范围内,按 Tidy First 原则先做结构改动,否则作为独立重构提出。
无效理由:组件太长、存在重复代码、分离关注点让调用点更干净、更易测试,均不构成创建 Hook 的充分理由。
适合的 Hook:以 React 状态转换为核心职责(如 useDisclosure、useSelection、useStepper、useToggle、useDebouncedValue),或以 React 生命周期/副作用为核心职责(如 useWindowSize、useIntersectionObserver、useFocusTrap、useOnClickOutside、useQuery、useChatRoomSubscription、useGeolocation)。
应避免的 Hook:仅重命名已有依赖的薄包装,如 useUserProfileQuery、useWorkspaceRouteParams、useCurrentWorkspace,通常改为普通函数处理传入参数或返回值。业务逻辑 Hook 需具体判断,看职责是否清晰、是否隐藏调用方应知的依赖、是否把逻辑困在 Hook 内使组件无法控制流程。
限制:Controller Pattern Hook 属于项目特定设计策略,仅在项目已使用该模式时允许,需与特定组件 1:1、同目录、命名明确、不用于复用、只承担目标组件可承担的职责;若被多个组件使用即为失败信号。自定义 Hook 不是缩短代码的工具。