react-admin 软删除实践:用 `<ShowDeletedBase>` 无头组件渲染已删除记录详情
2026/9/21 19:31:00 网站建设 项目流程
  • 前端
  • UI组件

【免费下载链接】react-admin

A 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
点击查看免费下载

导读

在 react-admin(Enterprise Edition)的软删除(soft delete)功能集中,<ShowDeletedBase>是面向"已删除记录"详情展示的无头(headless)组件,它替代常规的<ShowBase>,以完全自定义的方式渲染被删除记录的内容,并向下层组件提供与<ShowBase>一致的ShowContext。阅读本文后,你将掌握如何在自定义"回收站"页面中组合<DeletedRecordsListBase><DeletedRecordRepresentation><ShowDeletedBase>,复现并扩展官方文档中的完整示例,同时理解其底层数据流(dataProvider.getOneDeleted()与 react-query)与权限约束。

一、功能定位:为什么要用<ShowDeletedBase>

在 react-admin 的软删除生态中,常规的<ShowBase>通过dataProvider.getOne()获取记录并放入ShowContext,用于构建完全自定义的展示页(参见 ShowBase 文档)。而删除后的记录无法再通过getOne()读取——它需要专用的dataProvider.getOneDeleted()数据方法。<ShowDeletedBase>正是为这一场景设计的替代品:

  • 它替代<ShowBase>,专门用于展示一条已删除记录
  • 它向下层 children 提供<ShowBase>完全相同的ShowContext,因此<ShowBase>能用的 children 组件(如WithRecordTextField等)在这里同样可用;
  • 作为无头组件,它不渲染任何默认布局、标题或操作按钮,把展示方式完全交给开发者。

与同系列的<ShowDeleted>(见 docs/ShowDeleted.md,对应完整版<Show>的替代品)相比,<ShowDeletedBase>更轻量、更灵活:前者适合配合<DeletedRecordsList>detailComponents弹窗使用,而<ShowDeletedBase>适合嵌入DeletedRecordsListBase的自定义列表,以纯手写 UI 展示详情。

注意:<ShowDeletedBase>属于 react-admin Enterprise Edition 功能,需要有效的企业版订阅才能使用,源码位于闭源的@react-admin/ra-core-ee包中(本文档为其官方文档,见 docs_headless/src/content/docs/ShowDeletedBase.md)。

二、安装@react-admin/ra-core-ee

<ShowDeletedBase><DeletedRecordsListBase><DeletedRecordRepresentation>以及DeletedRecordType类型均从@react-admin/ra-core-ee导出。安装方式与其他 react-admin 包一致:

npm install --save @react-admin/ra-core-ee # 或 yarn add @react-admin/ra-core-ee

该包是 Enterprise Edition(@react-admin/*系列)的组成部分,与开源版 react-admin 中的ra-corera-ui-materialui等包协同工作。示例中还会从开源包导入CoreAdminCustomRoutesWithRecordWithListContext等基础组件。

三、完整用法示例:自定义"回收站"详情视图

官方文档给出了一个端到端可运行的示例,完整覆盖了"删除记录列表 → 点击查看详情 → 展示已删除记录内容"的完整链路:

import { CoreAdmin, CustomRoutes, WithRecord } from 'ra-core'; import { Route } from 'react-router-dom'; import { DeletedRecordsListBase, DeletedRecordRepresentation, ShowDeletedBase, type DeletedRecordType } from '@react-admin/ra-core-ee'; export const App = () => ( <CoreAdmin> ... <CustomRoutes> <Route path="/deleted" element={ <DeletedRecordsListBase> <WithListContext render={({ isPending, data }) => isPending ? null : ( <ul> {data.map(record => ( <li key={record.id}> <DeletedItem record={record} /> </li> ))} </ul> )} /> </DeletedRecordsListBase> } /> </CustomRoutes> </CoreAdmin> ); const DeletedItem = ({ record }: { record: DeletedRecordType }) => { const [showDetails, setShowDetails] = React.useState(false); return ( <> <div><strong>{record.resource}</strong></div> <DeletedRecordRepresentation record={record} /> <div> <button onClick={() => setShowDetails(true)}>Details</button> </div> {showDetails ? ( <ShowDeletedBase record={record}> <WithRecord render={record => <p>{record.title}</p>} /> <WithRecord render={record => <p>{record.description}</p>} /> <button onClick={() => setShowDetails(false)}>Close</button> </ShowDeletedBase> ) : null} </> ) }

示例的关键点拆解:

  1. 列表层<DeletedRecordsListBase>通过dataProvider.getListDeleted()获取已删除记录列表,并以ListContext提供给 children;WithListContext从中解构出isPendingdata进行渲染。它自带排序、筛选与分页能力,详见 DeletedRecordsListBase 文档。
  2. 单条摘要层record的类型是DeletedRecordType,其结构与useDeletedRecordsListController的返回值一致,形如{ id: 123, resource: 'posts', deleted_at: '2025-03-25T12:32:22Z', deleted_by: 'test', data: { ...原记录字段 } }——resource标识来源资源,data保存被删除时的原始记录内容,deleted_by/deleted_at记录操作者与删除时间(参见 useDeletedRecordsListController 文档)。<DeletedRecordRepresentation>负责渲染记录的"表征"(record representation),详见 DeletedRecordRepresentation 文档。
  3. 详情层:点击 Details 后,将record传入<ShowDeletedBase record={record}>,其内部会建立ShowContext,使WithRecord能够读取到被删除记录的原始字段record.titlerecord.description)。注意:由于data字段存放原记录内容,WithRecord中回调收到的record参数即为原始记录对象,可直接按字段名访问。

四、Props 全解

官方文档对<ShowDeletedBase>的 Props 给出了精炼的表格,完整整理如下:

PropRequiredTypeDefaultDescription
childrenRequiredElement用于渲染已删除记录内容的组件(如WithRecordSimpleShowLayout等)。
recordOptionalRaRecord要展示的已删除记录。若未提供,则使用最近的RecordContext中的记录。

4.1children(必填)

children是渲染已删除记录的实际内容。由于<ShowDeletedBase>建立的是与<ShowBase>相同的ShowContext,你可以自由组合各类上下文感知组件:

  • WithRecord:以 render prop 形式接收当前记录,实现完全自定义的字段渲染;
  • 开源版展示组件(如TextFieldSimpleShowLayout):它们通过useRecordContext()读取记录,只要包在<ShowDeletedBase>内即可正常工作;
  • 任意自定义按钮、交互元素:在官方示例中,Details / Close 按钮就与字段渲染混排在同一 children 树中。

4.2record(可选)

record用于显式指定要展示的已删除记录。两个常见使用场景:

  • 列表详情联动:像官方示例那样,从WithListContextdata中取出DeletedRecordType对象后直接传入;
  • 省略传参:若组件外层已经存在RecordContext(例如在<DeletedRecordsList>的行上下文中),可省略record,组件会自动从最近的RecordContext读取记录。

五、底层原理:数据从哪来

<ShowDeletedBase>本身是展示型无头组件,它自身的记录数据通过recordprop 或RecordContext提供;但在更常见的场景中(不手动传入 record),"按 id 获取已删除记录"这一数据获取动作由配套 hook 完成:

  • 底层数据方法为dataProvider.getOneDeleted(),对应 hook 为useGetOneDeleted。该 hook 在组件挂载时调用dataProvider.getOneDeleted(),按 id 查询单条已删除记录,并返回{ data, isPending, error, refetch }
  • 它的 react-query query key 为['getOneDeleted', { id: String(id), meta }]meta参数可选,可向 data provider 传递字段选择等附加信息;
  • 返回的data同样符合DeletedRecordType结构,可通过deletedRecord.data.usernamedeletedRecord.deleted_by等方式访问原始记录与删除元信息;
  • <ShowDeletedBase>提供的ShowContext与开源版<ShowBase>(其背后是useShowControllerhook)保持同一形态,这正是 children 组件可以无差别复用的根本原因——从组件树契约上看,展示一条"被删除的记录"与展示一条"普通记录"对 UI 层是透明的。

从源码结构看,可以推断@react-admin/ra-core-ee内部会将record/RecordContext的记录放入ShowContext,并复用 react-admin 的上下文机制完成数据下发;由于该包闭源,具体实现细节以官方文档描述为准。

六、安全与权限约束

虽然<ShowDeletedBase>本身只负责渲染,但它所在的"删除记录"页面整体受到 react-admin 企业版的访问控制约束。以同系列的useDeletedRecordsListController/DeletedRecordsListBase为例(两者同属ra-soft-delete能力集):

  • 默认要求用户已认证,匿名访问会被重定向到登录页;可通过disableAuthentication关闭(见 DeletedRecordsListBase 文档);
  • 若 authProvider 实现了访问控制(Access Control),列表控制器会调用authProvider.canAccess(),参数为{ resource: 'ra-soft-delete', action: 'list_deleted_records' };无权限用户将被重定向到 Access Denied 页面(见 useDeletedRecordsListController 文档)。

因此,在部署<ShowDeletedBase>时,建议将详情展示路由同样纳入上述鉴权体系,确保"查看已删除记录"与"列出已删除记录"的权限口径一致。

七、与相关组件的协作全景

<ShowDeletedBase>不是孤立组件,它处于 react-admin 软删除功能集的"详情展示"一环。一张完整的能力地图如下:

环节组件 / Hook数据方法上下文文档
已删除记录列表<DeletedRecordsListBase>/useDeletedRecordsListControllergetListDeleted()ListContextDeletedRecordsListBase
单条获取useGetOneDeletedgetOneDeleted()直接返回值useGetOneDeleted
单条表征<DeletedRecordRepresentation>读取recordRecordContextDeletedRecordRepresentation
详情展示(无头)<ShowDeletedBase>读取record/RecordContextShowContextShowDeletedBase
详情展示(完整版)<ShowDeleted>上下文注入ShowContextShowDeleted
软删除 data providerSoftDeleteDataProvidergetListDeleted/getOneDeleted-SoftDeleteDataProvider

选型建议:

  • 追求完全自定义、嵌入式的详情视图(如手写<ul>+WithRecord,或内嵌在列表行中展开)时,选<ShowDeletedBase>
  • 希望开箱即用的弹窗详情(配合<DeletedRecordsList>detailComponents<DeletedRecordsTable>行点击)时,选<ShowDeleted>

两条路线共用同一ShowContext契约,迁移成本很低——children 组件可以原样复用。

八、小结

<ShowDeletedBase>是 react-admin Enterprise Edition 软删除能力中"详情展示"一环的轻量选择:它以<ShowBase>同款的无头形态与ShowContext契约为已删除记录提供完全自定义的渲染入口,配合<DeletedRecordsListBase><DeletedRecordRepresentation>WithRecord,即可在不依赖任何默认布局的前提下,构建出贴合业务需求的回收站详情页。理解其"record来源 +ShowContext下发 +getOneDeleted数据通路"的三角结构,是安全、正确地使用它的关键。

  • 前端
  • UI组件

【免费下载链接】react-admin

A 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
点击查看免费下载
上一篇:Blackbone深度解析:Windows内存操作与进程防护技术实现原理
下一篇:Effect ManagedRuntime 支持 await using:Symbol.asyncDispose 变更集与资源自动释放机制解读

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询