)
react-admin 软删除实战useSoftDelete Hook 完整指南参数、用法与源码对照【免费下载链接】react-adminA frontend Framework for single-page applications on top of REST/GraphQL APIs, using TypeScript, React and Material Design项目地址: https://gitcode.com/gh_mirrors/re/react-adminuseSoftDelete是 react-admin 企业版扩展包react-admin/ra-soft-delete提供的 mutation Hook用于在触发回调时调用dataProvider.softDelete()按id将单条记录软删除标记删除而非物理删除。本文以 docs/useSoftDelete.md 为核心骨架结合仓库内useDelete的开源实现源码完整讲解该 Hook 的签名、参数、两种调用方式、authorId自动填充机制、TypeScript 泛型以及它背后的数据提供者契约让你能在自定义按钮、表单动作或任意组件中安全可靠地实现归档/回收站能力。软删除与useSoftDelete的定位在传统 CRUD 中useDelete调用dataProvider.delete()会从数据库物理移除记录。而很多业务审计、回收站、可恢复归档需要一种软删除记录并未真正消失只是被标记为已删除可以随时浏览、恢复。useSoftDelete正是为此设计它与useDelete工作方式完全一致区别仅在于底层调用的是dataProvider.softDelete()而非dataProvider.delete()可参见 docs/useDelete.md 中的说明。该 Hook 是 Enterprise Edition 附加组件ra-soft-delete的一部分需要安装并激活企业版许可证npm install --save react-admin/ra-soft-delete # 或 yarn add react-admin/ra-soft-delete安装后在 react-admin 应用中无需额外配置即可在任意自定义组件中使用该 Hook数据提供者端的方法实现见 docs/SoftDeleteDataProvider.md。Hook 签名与参数详解useSoftDelete的完整签名如下const [softDeleteOne, { data, isPending, error }] useSoftDelete( resource, { id, authorId, previousData, meta }, options, );参数类型必填说明resourcestring是目标资源名例如postsparams.idIdentifier是待软删除记录的标识符params.authorIdIdentifier否执行删除操作的用户 ID未提供时自动填充见下文params.previousDataRecord否软删除前的记录快照用于乐观更新与回滚params.metaany否透传给 data provider 的元数据如自定义请求头optionsUseMutationOptions否react-queryuseMutation选项可含onSuccess、onError、onSettled、mutationMode等返回值是一个二元组第一个元素softDeleteOne触发软删除的回调函数可以像调用 Hook 一样接收(resource, params, options)第二个元素mutation 状态对象常用data删除成功返回的记录、isPending请求进行中、error失败原因此外还暴露 react-queryuseMutation的全部状态与方法如reset、isIdle、isSuccess、isError。从开源仓库中useDelete的实现packages/ra-core/src/dataProvider/useDelete.ts可以推断useSoftDelete的内部结构与之类似通过useDataProvider()取得 data provider将 mutation 委托给useMutationWithMutationMode并校验resource与id非空后才会调用dataProvider.softDelete()。两种参数传递方式何时传参更合理useSoftDelete的参数既可以绑定在 Hook 调用时传入也可以在触发softDeleteOne回调时传入// 方式一调用 Hook 时传参 const [softDeleteOne, { data, isPending, error }] useSoftDelete( likes, { id: record.id, previousData: record }, ); // 方式二触发回调时传参 const [softDeleteOne, { data, isPending, error }] useSoftDelete(); softDeleteOne(likes, { id: record.id, previousData: record });官方文档明确建议当两种方式都可行时优先选择在调用softDeleteOne回调时传参第二种示例。这样 Hook 与具体资源/记录解耦组件更易复用例如同一按钮组件可以在不同记录上下文下被多次使用。这一机制与useDelete的useEvent封装一致。查看 useDelete.ts 可以看到回调签名是deleteOne( callTimeResource resource, // 回调时传参优先缺省回退到 Hook 参数 callTimeParams {}, // 回调时的 params 与 Hook 时 params 合并 callTimeOptions {}, )即调用时刻传入的resource、params会覆盖 Hook 调用时刻的默认值两者通过参数展开合并这保证了两种写法行为等价。authorId自动填充的审计字段params.authorId是软删除特有的参数用于记录谁删除了这条记录是审计与追责的关键数据。官方文档给出的 Tip 是如果未显式提供authorIduseSoftDelete会自动通过authProvider.getIdentity()获取当前用户身份并取返回身份对象的id字段作为authorId若authProvider未实现getIdentity或返回对象没有id字段则该字段留空。这意味着只要你的authProvider实现了getIdentity例如返回{ id: 123, fullName: John Doe }软删除请求会自动携带authorId: 123无需手工传入authorId的填充发生在请求发出之前最终会随softDelete参数一起发送给 data provider见 docs/SoftDeleteDataProvider.md 中softDelete方法的{ id, authorId }参数解构示例建议始终保证getIdentity返回的id是稳定、可持久化的标识如用户表主键而非易变字段。实战示例自定义软删除按钮官方文档给出了两种完整的组件示例以下完整保留并补充注释// 写法一在调用 Hook 时设置参数 import { useRecordContext } from react-admin; import { useSoftDelete } from react-admin/ra-soft-delete; const SoftDeleteButton () { const record useRecordContext(); const [softDeleteOne, { isPending, error }] useSoftDelete( likes, { id: record.id, previousData: record } // authorId 可省略自动填充 ); const handleClick () { softDeleteOne(); } if (error) { return pERROR/p; } return button disabled{isPending} onClick{handleClick}Delete/button; };// 写法二官方推荐在调用 softDeleteOne 回调时设置参数 import { useRecordContext } from react-admin; import { useSoftDelete } from react-admin/ra-soft-delete; const SoftDeleteButton () { const record useRecordContext(); const [softDeleteOne, { isPending, error }] useSoftDelete(); const handleClick () { softDeleteOne( likes, { id: record.id, previousData: record } ); } if (error) { return pERROR/p; } return button disabled{isPending} onClick{handleClick}Delete/button; };示例中的关键实践点useRecordContext()从 react-admin 的 RecordContext 读取当前记录配合列表、详情页等场景无需手工传 recordpreviousData: record传入删除前的完整记录快照供乐观更新在失败时回滚 UIisPending请求期间禁用按钮防止重复提交error失败时给出明确反馈示例中直接渲染错误提示。如果只是需要现成的按钮组件也可以直接使用react-admin/ra-soft-delete提供的SoftDeleteButton默认标签为 Archive支持mutationMode、mutationOptions、redirect、successMessage、访问控制等完整 props而useSoftDelete则用于需要完全掌控触发逻辑的自定义场景。TypeScript记录类型与错误类型的泛型收窄useSoftDelete接受两个泛型参数记录类型继承RaRecord与错误类型从而让onError、onSettled等回调获得完整类型推断useSoftDeleteProduct, Error(undefined, undefined, { onError: (error) { // TypeScript 知道 error 是 Error 类型 }, onSettled: (data, error) { // TypeScript 知道 data 是 Product 类型 // TypeScript 知道 error 是 Error 类型 }, });这与开源版useDelete的泛型设计一脉相承。查看 useDelete.ts 的类型定义export const useDelete RecordType extends RaRecord any, MutationError unknown, ( resource?: string, params: PartialDeleteParamsRecordType {}, options: UseDeleteOptionsRecordType, MutationError {} ): UseDeleteResultRecordType, MutationError { ... }可以推断useSoftDeleteProduct, Error中data被推断为Product | undefinederror被推断为Error回调中的data与error会随参数顺序自动关联收窄。底层原理从useDelete源码看 mutation 机制虽然react-admin/ra-soft-delete为闭源企业包但它在开源版 packages/ra-core/src/dataProvider/useDelete.ts 的基础上扩展而来两者共享同一套 mutation 架构因此可以从useDelete的实现理解useSoftDelete的运行机制mutation 核心Hook 内部通过useMutationWithMutationMode封装 react-query 的useMutationuseDelete.ts因此options支持 react-query 的onSuccess/onError/onSettled等选项并额外支持mutationMode与自定义mutationFnmutation 模式支持pessimistic默认、optimistic、undoable。useDelete的默认值是pessimistic而SoftDeleteButton的默认值为undoable点击后 5 秒内可撤销缓存更新updateCache删除成功后useDelete会自动从getList、getInfiniteList、getMany、getManyReference四种查询缓存中移除该记录并同步递减totaluseDelete.ts。useSoftDelete预计执行类似逻辑——不过软删除场景下记录从列表消失但仍存在于回收站因此删除后通常还需要使getListDeleted相关查询失效结算处理onSettled无论成功失败都会对快照中的 query key 执行invalidateQueries强制刷新useDelete.ts保证界面与服务器状态一致。理解这层机制后你可以在options中放心使用mutationMode: undoable提供撤销能力或通过onSuccess触发通知、跳转等副作用。配套生态数据提供者契约与 Hook 家族useSoftDelete只是软删除方案中的一环。要让整个方案跑通data provider 必须实现对应的softDelete方法完整接口见 docs/SoftDeleteDataProvider.mdconst dataProviderWithSoftDelete: SoftDeleteDataProvider { ...dataProvider, softDelete: (resource, params: SoftDeleteParams): SoftDeleteResult { const { id, authorId } params; // ... return { data: deletedRecord }; }, // softDeleteMany、getOneDeleted、getListDeleted、 // restoreOne、restoreMany、hardDelete、hardDeleteMany ... };仓库中每个 data provider verb 都对应一个独立 Hook详见 docs/SoftDeleteDataProvider.mddata provider 方法对应 Hook作用softDeleteuseSoftDelete软删除单条记录softDeleteManyuseSoftDeleteMany软删除多条记录getListDeleteduseGetListDeleted获取已删除记录列表getOneDeleteduseGetOneDeleted获取单条已删除记录restoreOneuseRestoreOne恢复单条已删除记录restoreManyuseRestoreMany恢复多条已删除记录hardDeleteuseHardDelete永久删除单条记录hardDeleteManyuseHardDeleteMany永久删除多条记录这些 Hook 的签名风格与useSoftDelete完全一致支持 Hook 调用时传参或回调时传参两种方式例如useRestoreOne。此外ra-soft-delete还内置了两个 data provider 构建器addSoftDeleteBasedOnResource把已删除记录统一存入deleted_records资源与addSoftDeleteInPlace在原资源内标记deleted_at/deleted_by并让查询自动过滤可直接套在基础 data provider 上启用全套能力。软删除记录的结构理解useSoftDelete返回的data需要先知道已删除记录的数据结构见 docs/SoftDeleteDataProvider.md字段类型说明idIdentifier删除记录条目的 IDresourcestring被删除记录所属资源名deleted_atstring删除时间ISO 8601 格式deleted_byIdentifier可选执行删除的用户 ID即上文authorIddataRecord删除前的原始记录数据{ id: 123, resource: products, deleted_at: 2025-06-06T15:32:22Z, deleted_by: johndoe, data: { id: 456, title: Lorem ipsum, teaser: Lorem ipsum dolor sit amet, body: Lorem ipsum dolor sit amet, consectetur adipiscing elit, }, }因此在useSoftDelete成功回调中取到的data即为这样一个删除记录条目原始内容可通过data.data访问后续若需恢复则用条目id调用useRestoreOne注意恢复时使用的是删除记录条目的id而非原始记录 ID详见 docs/useRestoreOne.md 中的警告。小结useSoftDelete把软删除单条记录封装成了一个高可用的 mutation Hook参数可灵活绑定authorId自动审计TypeScript 类型完备且与 react-query 生态深度集成。配合ra-soft-delete提供的数据提供者契约、SoftDeleteButton组件及DeletedRecordsList界面你可以在不写任何删除逻辑样板代码的前提下为 react-admin 应用构建出归档 → 浏览回收站 → 恢复/彻底删除的完整软删除闭环。【免费下载链接】react-adminA frontend Framework for single-page applications on top of REST/GraphQL APIs, using TypeScript, React and Material Design项目地址: https://gitcode.com/gh_mirrors/re/react-admin创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考