6.3 KiB
useCleaner 重构说明
本文档记录 src/renderer/src/hooks/useCleaner.ts 的第一阶段重构工作。目标不是一次性把整个 Cleaner 页面完全组件化,而是优先拆出共享类型、纯函数和 IPC 编排逻辑,让 useCleaner 从“大而全逻辑容器”逐步收敛为“组合层”。
1. 重构背景
重构前,useCleaner.ts 同时负责:
- 页面初始化
- 权限判断
- sessionStorage 持久化
- 校验请求
- 结果筛选
- 勾选状态处理
- 删除计划构建
- 保存物料变更
- Cleaner 执行编排
- 导出编排
- 弹窗确认
- 报告状态维护
这导致它虽然名义上是一个 hook,但实际上已经接近一个“前端页面服务总线”。
2. 重构目标
本次重构目标是:
- 提取共享类型,消除重复定义
- 提取纯函数,隔离无副作用逻辑
- 提取 IPC / 异步编排,隔离对
window.electron的直接调用 - 保持
useCleaner()返回值和CleanerPage.tsx使用方式不变
3. 重构后结构
graph TD
Page[CleanerPage.tsx]
Hook[useCleaner.ts]
subgraph CleanerHookModules[Cleaner Hook Modules]
Types[hooks/cleaner/types.ts]
Helpers[hooks/cleaner/helpers.ts]
Api[hooks/cleaner/api.ts]
end
subgraph ExternalDeps[External Dependencies]
Electron[window.electron]
Store[useAppStore / Toast]
Dialog[ConfirmDialog]
end
Page --> Hook
Hook --> Types
Hook --> Helpers
Hook --> Api
Hook --> Store
Hook --> Dialog
Api --> Electron
4. 本次拆分内容
4.1 共享类型
新增:
src/renderer/src/hooks/cleaner/types.ts
统一收敛了以下类型:
ValidationRequestValidationResultValidationStatsValidationResponsePayloadCleanerProgressCleanerReportDataCleanerInitializationResultCleanerConfigResult
这一步解决了原来多个文件重复定义同类类型的问题,比如:
useCleaner.tsuseValidation.tsExecutionReportDialog.tsx
4.2 纯函数与数据构造
新增:
src/renderer/src/hooks/cleaner/helpers.ts
提取出的纯函数包括:
getStoredBoolean()getStoredValidationMode()filterValidationResults()buildDeletionPlan()buildExportItems()
这些逻辑之前都散落在 useCleaner.ts 的 useMemo 或事件处理函数里,现在可以单独测试。
4.3 IPC 与异步编排
新增:
src/renderer/src/hooks/cleaner/api.ts
提取出的异步编排包括:
initializeCleanerPage()loadCleanerConfig()runValidationRequest()saveDeletionPlan()reloadManagers()runCleanerExecution()exportCleanerResults()
这样做之后,useCleaner.ts 不再需要在每个 handler 里直接拼接 window.electron.xxx 调用细节。
5. useCleaner 的角色变化
flowchart LR
subgraph Before[重构前]
A[useCleaner.ts]
A --> A1[本地状态]
A --> A2[筛选逻辑]
A --> A3[删除计划构建]
A --> A4[执行清理请求]
A --> A5[导出请求]
A --> A6[初始化请求]
A --> A7[共享类型定义]
end
subgraph After[重构后]
B[useCleaner.ts]
B --> B1[组合状态]
B --> B2[调用 helpers]
B --> B3[调用 api]
C[helpers.ts]
D[api.ts]
E[types.ts]
B --> C
B --> D
B --> E
end
重构后,useCleaner.ts 更接近“组合层”:
- 管理 React state
- 串联用户交互流程
- 调用 helpers 和 api
- 将最终能力暴露给页面
6. 受影响的文件
6.1 主体修改
src/renderer/src/hooks/useCleaner.tssrc/renderer/src/hooks/useValidation.tssrc/renderer/src/components/ExecutionReportDialog.tsx
6.2 新增模块
src/renderer/src/hooks/cleaner/types.tssrc/renderer/src/hooks/cleaner/helpers.tssrc/renderer/src/hooks/cleaner/api.ts
6.3 新增测试
tests/unit/cleaner-helpers.test.ts
7. 具体收益
7.1 类型一致性提升
之前 ValidationResult、CleanerProgress 在多个文件重复定义,修改字段时容易遗漏。
现在统一从 hooks/cleaner/types.ts 引用,降低了类型漂移风险。
7.2 可测试性提升
原先删除计划构建、筛选和导出映射逻辑只能通过 hook 间接覆盖。
现在这些逻辑已经被抽成纯函数,可以直接做单测。
7.3 Hook 复杂度下降
虽然 useCleaner.ts 还没有变成一个很小的文件,但其中的“细节密度”已经明显下降:
- 数据变换逻辑外提
- API 编排逻辑外提
- 重复类型移除
7.4 为下一步组件拆分做准备
后续如果要拆 CleanerPage.tsx:
- 左侧筛选区
- 表格工具栏
- 底部执行区
这些组件就可以直接消费已经整理好的 hook 能力,而不是继续把逻辑往页面里塞。
8. 验证方式
本次重构后执行了以下验证:
npm run typecheck:nodetests/unit/cleaner-helpers.test.tstests/unit/cleaner.test.ts
9. 新增测试覆盖点
tests/unit/cleaner-helpers.test.ts 覆盖了:
- 非管理员筛选逻辑
- 删除计划构建逻辑
- 导出数据构建逻辑
10. 仍然保留在 useCleaner 中的内容
为了控制改动风险,这次没有继续下沉以下能力:
ConfirmDialog的 Promise 封装- 编辑状态
editingCell / editValue isRunning / isExecuting / isReportDialogOpen等 UI 状态- 页面层直接依赖的完整返回对象
这些能力仍然保留在 useCleaner.ts,因为它们和当前页面交互绑定较深。
11. 下一步建议
基于目前的结构,建议下一阶段继续做:
- 拆
CleanerPage.tsx为“左侧筛选区”和“右侧结果与执行区”两个子组件。 - 将
showConfirmDialog()封装为独立 hook,例如useConfirmDialogController()。 - 将 inline edit 相关逻辑提取到更专门的 manager-assignment controller。
- 视情况把 Cleaner 相关状态进一步收敛到专门 store 或 domain hook 中。
12. 总结
这次 useCleaner 重构的核心价值,不是“让文件立刻变得很小”,而是先把最容易复用、最适合测试、最不应继续堆在 hook 里的部分拆出来。
它为接下来的页面组件拆分提供了一个更稳的基础,也让 Cleaner 模块开始从“页面驱动逻辑”向“模块化前端能力”转变。