ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

react-admin 软删除实战:深入掌握 `<DeletedRecordsList>` 组件

react-admin 软删除实战:深入掌握 `<DeletedRecordsList>` 组件 react-admin 软删除实战深入掌握DeletedRecordsList组件【免费下载链接】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-adminDeletedRecordsList是 react-admin 生态Enterprise Edition 附加包react-admin/ra-soft-delete中用于浏览、过滤、恢复或彻底删除已删除记录的列表组件。它通过dataProvider.getListDeleted()拉取数据并以DataTable呈现带分页、筛选与排序的完整管理界面。读完本文你将掌握该组件的路由接入方式、全部 Props 的用法与默认值、自定义详情弹窗、权限控制以及其底层控制器 Hook 的扩展思路。软删除场景下DeletedRecordsList的角色在 Soft Delete 功能概览 中react-admin 允许实现软删除记录并未真正从数据库移除而是被打上删除标记。用户可以在专用界面浏览所有被删除的记录、恢复它们restoreOne/restoreMany或彻底删除hardDelete/hardDeleteMany。DeletedRecordsList正是这个回收站界面的核心组件通过dataProvider.getListDeleted()获取已删除记录列表在DataTable中展示记录内置分页、筛选、排序表格内置恢复与彻底删除按钮点击行可在弹窗中查看被删除记录的原始数据。它适合与SoftDeleteButton、BulkSoftDeleteButton等按钮组件搭配使用列表页用软删除按钮删记录回收站页用DeletedRecordsList管理被删记录。快速上手安装与路由接入安装npm install --save react-admin/ra-soft-delete # 或 yarn add react-admin/ra-soft-delete该包属于 Enterprise Edition需要有效的 EE 许可证详见 SoftDeleteDataProvider 文档。路由接入DeletedRecordsList本身不需要任何属性即可工作但它的路由必须由你手动定义。由于它不属于任何Resource你需要借助CustomRoutes把它挂载到某个 URL// in src/App.js import { Admin, CustomRoutes } from react-admin; import { Route } from react-router-dom; import { DeletedRecordsList } from react-admin/ra-soft-delete; export const App () ( Admin ... CustomRoutes Route path/deleted element{DeletedRecordsList /} / /CustomRoutes /Admin );这样即完成接入列表自带简单过滤器、排序与分页。如果你还想在侧边菜单中放一个入口可以使用DeletedRecordsListMenuItem// in src/MyMenu.tsx import { Menu } from react-admin; import { DeletedRecordsListMenuItem } from react-admin/ra-soft-delete; export const MyMenu () ( Menu DeletedRecordsListMenuItem / ... /Menu );该菜单项默认跳转到/deleted路由可通过to属性修改如to/trash并继承Menu.Item的所有属性primaryText、children等。前置条件Data Provider 必须支持软删除DeletedRecordsList依赖dataProvider.getListDeleted()因此你的 data provider 需要实现软删除相关方法完整接口见 SoftDeleteDataProvider.mdsoftDelete/softDeleteMany软删除单条 / 多条记录getOneDeleted/getListDeleted按 ID 获取 / 分页筛选获取已删除记录restoreOne/restoreMany恢复记录hardDelete/hardDeleteMany彻底删除记录可选createMany批量创建默认实现是循环调用create。ra-soft-delete提供了两个开箱即用的 Builder 来扩展你的 data provider无需自建后端addSoftDeleteBasedOnResource把所有资源的已删除记录集中存进一个独立资源默认名为deleted_recordsaddSoftDeleteInPlace记录留在原资源中仅打上deleted_at/deleted_by标记查询方法自动过滤已删除记录。已删除记录的数据结构getListDeleted返回的每条已删除记录结构如下这是理解children与detailComponents中字段来源的基础字段说明id已删除记录的标识符resource该记录所属资源名deleted_at删除时间ISO 8601 格式deleted_by可选执行删除操作的用户标识data删除前的原始记录数据示例{ 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, }, }注意若使用addSoftDeleteInPlace应尽量避免在不带resource过滤条件的情况下调用getListDeleted底层是多次getList组合的朴素实现性能较差此时建议为每个资源各建一个DeletedRecordsList resource...页面见下文resource一节。Props 总览DeletedRecordsList的全部属性均为可选Prop类型默认值说明authLoadingReactNode-检查认证与权限期间渲染的组件debouncenumber500用户修改筛选/排序参数后调用 data provider 的防抖延迟毫秒childrenElementDeletedRecordsTable用于渲染已删除记录列表的组件detailComponentsRecordstring, ComponentType-各资源在已删除列表中的自定义详情展示组件disableAuthenticationbooleanfalse设为true关闭认证检查disableSyncWithLocationbooleanfalse设为true关闭列表参数与 URL 的同步emptyReactNode-列表为空时显示的组件errorReactNode-加载列表失败时渲染的组件filterobject-永久筛选值filterDefaultValuesobject-筛选表单的默认值loadingReactNode-加载列表期间渲染的组件mutationModestringundoable变更模式undoable、pessimistic、optimisticofflineReactNodeOffline无网络且缓存中尚无当前参数数据时渲染的组件paginationReactElementPagination分页组件perPagenumber10每页记录数queryOptionsobject-传给useQuery的选项resourcestring-要获取并展示的已删除记录所属资源sortobject{ field: deleted_at, order: DESC }初始排序参数storeKeystring或false-存储筛选与排序状态的 key传false禁用titlestring或ReactElement或false-App Bar 中显示的标题sxobject-组件的 CSS 样式按 Props 详解配置与定制authLoading认证等待视图默认在检查认证与权限期间渲染Loading。需要自定义时import { DeletedRecordsList } from react-admin/ra-soft-delete; export const CustomDeletedRecords () ( DeletedRecordsList authLoading{pChecking for permissions.../p} / );children自定义表格默认渲染DeletedRecordsTable即一个带恢复/彻底删除按钮的DataTable。你可以传入自定义DataTable覆盖列定义import { DataTable } from react-admin; import { DeletedRecordsList } from react-admin/ra-soft-delete; export const CustomDeletedRecords () ( DeletedRecordsList DataTable DataTable.Col sourceid / DataTable.Col sourceresource / DataTable.Col sourcedeleted_at / DataTable.Col sourcedeleted_by / DataTable.Col sourcedata.title labelTitle / /DataTable /DeletedRecordsList );由于data字段中保存的是删除前的原始记录你可以在DataTable.Col中使用点路径如data.title直接映射到原记录字段。debounce筛选防抖默认用户在筛选表单输入后需等待 500ms 无操作基于lodash.debounce才调用 data provider避免高频无效请求。可通过debounce调整时长毫秒// 等待 1 秒而不是默认的 500 毫秒 const DeletedRecordsWithDebounce () DeletedRecordsList debounce{1000} /;detailComponents自定义详情弹窗默认点击表格行时会在弹窗中用ShowGuesser展示已删除记录的数据。detailComponents允许你按资源名定制弹窗内容其写法与经典Show页面一致但必须使用ShowDeleted代替Show——因为Show会向 data provider 获取记录的新版本而该记录已被删除无法获取。import { Admin, CustomRoutes, SimpleShowLayout, TextField } from react-admin; import { Route } from react-router-dom; import { DeletedRecordsList, ShowDeleted } from react-admin/ra-soft-delete; const ShowDeletedBook () ( ShowDeleted SimpleShowLayout TextField sourcetitle / TextField sourcedescription / /SimpleShowLayout /ShowDeleted ); export const App () ( Admin ... CustomRoutes Route path/deleted element{ DeletedRecordsList detailComponents{{ books: ShowDeletedBook, }} / } / /CustomRoutes /Admin );ShowDeleted的 Props 与Show基本一致但resource、id、queryOptions由上下文传入、不可覆盖详见 ShowDeleted.md。disableAuthentication允许匿名访问默认DeletedRecordsList要求用户已认证匿名访问会被重定向到登录页。需要开放匿名访问时const AnonymousDeletedRecords () DeletedRecordsList disableAuthentication /;disableSyncWithLocation关闭 URL 参数同步默认情况下列表参数排序、分页、筛选会与 URL 查询串通过react-routerlocation以及 Store 同步。若希望每个DeletedRecordsList实例各自维护独立的本地状态可关闭同步缺点是点击浏览器后退按钮无法恢复此前的参数const DeletedRecordsWithoutSyncWithLocation () DeletedRecordsList disableSyncWithLocation /;提示disableSyncWithLocation默认同时关闭列表参数在 Store 中的持久化。若仍想持久化可配合自定义storeKeyconst DeletedRecordsSyncWithStore () DeletedRecordsList disableSyncWithLocation storeKeydeletedRecordsListParams /;error加载失败视图默认加载失败时直接渲染 children。可传入error属性展示错误组件import { DeletedRecordsList } from react-admin/ra-soft-delete; export const CustomDeletedRecords () ( DeletedRecordsList error{pSomething went wrong while loading your posts!/p} / );filter永久筛选filter用于设置用户无法关闭的永久筛选例如只展示 posts 资源的删除记录const DeletedPostsList () ( DeletedRecordsList filter{{ resource: posts }} / );最终发送给 data provider 的筛选参数 用户筛选通过筛选表单设置与永久筛选的组合用户无法覆盖filter中设定的值。filterDefaultValues筛选默认值用于设置筛选表单的初始值与filter的关键区别在于filterDefaultValues可被用户覆盖filter的值则始终会发给 data provider。三者优先级可归纳为const filterSentToDataProvider { ...filterDefaultValues, ...filterChosenByUser, ...filter };const CustomDeletedRecords () ( DeletedRecordsList filterDefaultValues{{ resource: posts }} / );loading加载中视图默认加载期间渲染 children。可在loading属性中展示加载组件import { Loading } from react-admin; import { DeletedRecordsList } from react-admin/ra-soft-delete; export const CustomDeletedRecords () ( DeletedRecordsList loading{Loading /} / );mutationMode变更模式列表中的恢复与彻底删除按钮属于数据变更mutation。react-admin 提供三种模式决定副作用重定向、通知等的执行时机pessimistic先调用 data provider成功后才在本地应用变更并执行副作用optimistic立即在本地应用变更并执行副作用再调用 data provider若失败则刷新页面并弹出错误通知undoable默认立即本地应用变更并执行副作用同时弹出带撤销按钮的通知。若用户点击撤销则变更永远不会发送给 data provider 并刷新页面否则 5 秒后发送。若 data provider 返回错误刷新页面并显示错误通知。undoable是 react-admin 乐观渲染策略的一部分交互更即时。可通过mutationMode修改并作用于表格内所有按钮const OptimisticDeletedRecords () ( DeletedRecordsList mutationModeoptimistic / );const PessimisticDeletedRecords () ( DeletedRecordsList mutationModepessimistic / );提示当模式不是undoable时DeletePermanentlyButton与RestoreButton在调用 data provider 前会先显示确认对话框。offline离线视图默认在无网络且缓存中还没有当前参数页码、排序等对应的记录时渲染Offline组件。可自定义import { DeletedRecordsList } from react-admin/ra-soft-delete; import { Alert } from mui/material; const offline Alert severitywarningNo network. Could not load the posts./Alert; export const CustomDeletedRecords () ( DeletedRecordsList offline{offline} / );pagination与perPage分页控制默认列表底部渲染一组分页控件可用pagination替换import { Pagination } from react-admin; import { DeletedRecordsList } from react-admin/ra-soft-delete; const DeletedRecordsPagination () Pagination rowsPerPageOptions{[10, 25, 50, 100]} /; export const DeletedRecordsWithCustomPagination () ( DeletedRecordsList pagination{DeletedRecordsPagination /} / );perPage默认每页 10 条可覆盖const DeletedRecordsWithCustomPagination () DeletedRecordsList perPage{25} /;注意默认分页组件的rowsPerPageOptions仅含 5、10、25、50。若把perPage设为集合外的值如 6必须同时自定义分页组件以允许该值否则会报错const DeletedRecordsWithCustomPagination () ( - DeletedRecordsList perPage{6} / DeletedRecordsList perPage{6} pagination{Pagination rowsPerPageOptions{[6, 12, 24, 36]} /} / );queryOptions透传 react-query 选项queryOptions会被透传给底层的 react-queryuseQuery。例如传递自定义meta给dataProvider.getListDeleted()import { DeletedRecordsList } from react-admin/ra-soft-delete; const CustomDeletedRecords () ( DeletedRecordsList queryOptions{{ meta: { foo: bar } }} / );挂载时 react-admin 将以meta: { foo: bar }调用dataProvider.getListDeleted()。也可用queryOptions覆盖默认的错误副作用。默认调用失败时 react-admin 显示错误通知可改为自定义通知并重定向import { useNotify, useRedirect } from react-admin; import { DeletedRecordsList } from react-admin/ra-soft-delete; const CustomDeletedRecords () { const notify useNotify(); const redirect useRedirect(); const onError (error) { notify(Could not load list: ${error.message}, { type: error }); redirect(/dashboard); }; return ( DeletedRecordsList queryOptions{{ onError }} / ); }onError接收来自dataProvider.getListDeleted()的错误对象即标准的 JavaScriptError错误格式约定见 DataProviderWriting.md。resource限定资源不指定resource时DeletedRecordsList会获取所有资源的已删除记录并显示资源筛选器。传入resource后只展示该资源的删除记录且不再显示筛选器const DeletedPosts () ( DeletedRecordsList resourceposts / );标题也会随之更新其翻译 key 为ra-soft-delete.deleted_records_list.resource_title。sort默认排序sort定义默认排序的field与order用户仍可点击列头改变排序const PessimisticDeletedRecords () ( DeletedRecordsList sort{{ field: id, order: ASC }} / );storeKey多实例状态隔离默认 react-admin 把列表参数排序、分页、筛选保存在 localStorage用户返回列表时可保持离开时的状态。DeletedRecordsList使用固定 keyra-soft-delete.listParams存储。当页面需要多个DeletedRecordsList且各自保持独立状态时必须为每个实例指定唯一的storeKey传false可完全关闭参数与选择状态的持久化import { Admin, CustomRoutes } from react-admin; import { Route } from react-router-dom; import { DeletedRecordsList } from react-admin/ra-soft-delete; const Admin () { return ( Admin dataProvider{dataProvider} CustomRoutes Route path/books/deleted element{ DeletedRecordsList filter{{ resource: books }} storeKeydeletedBooks / } / Route path/authors/deleted element{ DeletedRecordsList filter{{ resource: authors }} storeKeydeletedAuthors / } / /CustomRoutes Resource namebooks / /Admin ); };提示storeKey实际上会传给底层的useDeletedRecordsListControllerHook复杂场景可直接使用该 Hook见 useDeletedRecordsListController.md。注意无论storeKey字符串如何设置行选择状态selection始终绑定在全局 key 上。这是刻意的设计——如果行选择不全局存储当用户彻底删除或恢复某记录时该行可能保持选中状态而无法取消。若需允许自定义选择状态的storeKey你必须自行实现useDeletedRecordsListController并向useRecordSelection传入自定义 key同时自己实现删除按钮、在删除/恢复时手动取消选中。若将storeKey设为false则可完全退出包括选择在内的所有 Store 交互。title标题默认标题的翻译 key 为ra-soft-delete.deleted_records_list.title。可自定义支持字符串、React 元素或false禁用标题const DeletedRecordsWithTitle () DeletedRecordsList titleBeautiful Trash /;sxCSS APIDeletedRecordsList接受常规className也可通过sx覆盖注入到内部组件的类名语法见 SX.md。可用的子类Rule name说明 .RaDeletedRecordsList-filters筛选容器 .RaDeletedRecordsList-tableDataTable .RaDeletedRecordsList-dialog点击行时弹出的详情对话框const BeautifulDeletedRecordsList () ( DeletedRecordsList sx{{ backgroundColor: yellow, .RaDeletedRecordsList-filters: { backgroundColor: red, }, }} / );提示DeletedRecordsList的全局 CSS 类名为RaDeletedRecordsList可通过主题覆盖theme overrides一次定制所有实例的样式。访问控制Access Control若你的authProvider实现了 Access Control权限控制DeletedRecordsList仅当用户对虚拟资源ra-soft-delete拥有deleted_records访问权限时才显示。组件会以如下参数调用authProvider.canAccess(){ action: list_deleted_records, resource: ra-soft-delete }无权限用户将被重定向到 Access Denied 页面。恢复按钮的权限动作是restore{ action: restore, resource: ra-soft-delete, record: [current record] }彻底删除按钮的权限动作是delete{ action: delete, resource: ra-soft-delete, record: [current record] }深入底层控制器 Hook 与数据 HookuseDeletedRecordsListControlleruseDeletedRecordsListController是DeletedRecordsList的 headless 逻辑层从 URL 读取列表参数、调用dataProvider.getListDeleted()、准备修改分页/筛选/排序/选择的回调返回值符合 ListContext 形状。用它可以基于其他 UI 组件库构建自定义的已删除记录列表import { ListContextProvider } from react-admin; import { useDeletedRecordsListController } from react-admin/ra-soft-delete; const MyDeletedRecords ({children}: { children: React.ReactNode }) { const deletedRecordsListController useDeletedRecordsListController(); return ( ListContextProvider value{deletedRecordsListController} {children} /ListContextProvider ); };其参数与DeletedRecordsList的 Props 一一对应默认值相同debounce: 500、disableAuthentication: false、disableSyncWithLocation: false、perPage: 10、sort: { field: deleted_at, order: DESC }等。返回值包括数据data、total、isPending、isFetching、isLoading、分页page、perPage、setPage、hasPreviousPage、hasNextPage、排序sort、setSort、筛选filterValues、setFilters、选择selectedIds、onSelect、onToggleItem、onUnselectItems及defaultTitle、refetch等。例如用SimpleList直接渲染已删除记录此处data元素是已删除记录对象原始数据在其data字段中故primaryText写作%{data.title}import { SimpleList } from react-admin; import { useDeletedRecordsListController } from react-admin/ra-soft-delete; const CustomDeletedRecords () { const { isPending, error, data, total } useDeletedRecordsListController({ filter: { resource: posts } }) if (error) return divError!/div; return ( SimpleList data{data} total{total} isPending{isPending} primaryText%{data.title} / ); }useDeletedRecordsListController同样要求认证与ra-soft-delete资源上的list_deleted_records权限disableAuthentication可关闭认证同时关闭访问控制。useGetListDeleted如需在自定义组件中直接取数可使用useGetListDeletedHook。它挂载时调用dataProvider.getListDeleted()支持分页、排序、筛选与metareact-query 的 query key 为[getListDeleted, { pagination, sort, filter, meta }]import { useGetListDeleted } from react-admin/ra-soft-delete; const LatestDeletedPosts () { const { data, total, isPending, error } useGetListDeleted( { filter: { resource: posts }, pagination: { page: 1, perPage: 10 }, sort: { field: deleted_at, order: DESC } } ); if (isPending) { return Loading /; } if (error) { return pERROR/p; } return ( h1Latest deleted posts/h1 ul {data.map(deletedRecord li key{deletedRecord.id}{deletedRecord.data.title}/li )} /ul p{data.length} / {total} deleted posts/p / ); };它还支持泛型参数以启用类型提示useGetListDeletedPost(...)此时data的类型为DeletedRecordTypePost[]。分页、排序、筛选参数的语义与useGetList一致详见 useGetListDeleted.md。相关文档索引软删除是一套完整的生态以下文档可帮助你继续深入SoftDeleteDataProvider.mddata provider 软删除方法全量与两种 BuilderSoftDeleteButton.md / BulkSoftDeleteButton.md列表页软删除按钮useSoftDelete.md / useSoftDeleteMany.md软删除变更 HookuseRestoreOne.md / useRestoreMany.md恢复 HookuseHardDelete.md / useHardDeleteMany.md彻底删除 HookuseGetOneDeleted.md获取单条已删除记录ShowDeleted.md已删除记录详情组件useDeletedRecordsListController.md列表控制器 Hook 完整参数与返回值DeletedRecordsListMenuItem.md侧边菜单入口组件Features.mdSoft Delete 在 react-admin 功能总览中的定位。小结DeletedRecordsList是 react-admin 软删除方案中的回收站界面它以DataTable呈现已删除记录内置筛选、排序、分页支持恢复与彻底删除并可通过children、detailComponents、pagination、sx等属性深度定制。理解其数据来源getListDeleted与已删除记录结构、状态同步机制storeKey、disableSyncWithLocation和权限模型ra-soft-delete虚拟资源即可在项目中快速搭建安全、可维护的删除记录管理模块需要完全自定义 UI 时useDeletedRecordsListController提供了等价的 headless 能力。【免费下载链接】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),仅供参考
返回列表