react-admin 数据获取核心 Hook:useGetList 完整实战指南
react-admin 数据获取核心 HookuseGetList 完整实战指南【免费下载链接】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-adminuseGetList是 react-admin 中最常用的数据获取 Hook它在组件挂载时调用dataProvider.getList()用于拉取记录列表并原生支持分页pagination、排序sort与过滤filter。本文基于 react-admin 官方文档与 ra-core 源码从语法签名、请求参数、返回值、渲染接入、缓存机制到 TypeScript 用法系统讲解该 Hook 的使用方式与底层实现帮助你写出数据驱动的列表、下拉选单与自定义页面。useGetList 是什么useGetList是 react-admin 提供的一个 React Hook封装了数据提供器Data Provider的getList()方法。它遵循 react-query 的声明式数据获取模型你只需声明要什么数据Hook 便自动处理请求生命周期、加载状态、错误状态、缓存与重试。它的定位非常明确组件挂载时自动发起请求无需手动触发完整支持分页、排序、过滤与meta扩展参数返回值随请求状态实时更新包含isPending、error、refetch等状态字段基于 react-query 缓存同参数重复调用会命中缓存。从源码看useGetList的实现位于 packages/ra-core/src/dataProvider/useGetList.ts并通过 packages/ra-core/src/dataProvider/index.ts 对外导出最终由react-admin包统一暴露。它的核心实现就是一层对 TanStack QueryuseQuery的封装const result useQueryGetListResultRecordType, ErrorType, GetListResultRecordType({ queryKey: [resource, getList, { pagination, sort, filter, meta }], queryFn: queryParams dataProvider.getListRecordType(resource, { pagination, sort, filter, meta, signal: dataProvider.supportAbortSignal true ? queryParams.signal : undefined, }) .then(({ data, total, pageInfo, meta }) ({ data, total, pageInfo, meta })), ...queryOptions, });语法签名useGetList接收三个参数资源名、请求参数对象与 react-query 选项对象。const { data, total, isPending, error, refetch, meta } useGetList( resource, { pagination: { page, perPage }, sort: { field, order }, filter, meta }, options );参数一resource字符串类型的资源名称例如posts、comments。它决定了请求发送到哪个资源端点。参数二请求参数均有默认值参数类型默认值说明pagination{ page: number, perPage: number }{ page: 1, perPage: 25 }分页参数page为页码从 1 开始perPage为每页条数sort{ field: string, order: ASC \| DESC }{ field: id, order: DESC }排序参数field为字段名order为排序方向filterobject{}过滤条件键值对形式例如{ title: hello, world }metaanyundefined可选任何你想传给数据提供器的附加数据这些默认值在源码中有明确实现useGetList.tsconst { pagination { page: 1, perPage: 25 }, sort { field: id, order: DESC }, filter {}, meta, } params;需要注意即使你不传任何参数请求也会携带默认的分页与排序。对应地GetListParams类型定义于 packages/ra-core/src/types.ts包含pagination、sort、filter、meta与signal五个可选字段。参数三optionsoptions是可选的会被原样透传给 TanStack Query v5 的useQuery。可用的选项包括cacheTime、enabled、initialData、initialDataUpdatedAt、isDataEqual、keepPreviousData、meta、notifyOnChangeProps、notifyOnChangePropsExclusions、onError、onSettled、onSuccess、placeholderData、queryKeyHashFn、refetchInterval、refetchIntervalInBackground、refetchOnMount、refetchOnReconnect、refetchOnWindowFocus、retry、retryOnMount、retryDelay、select、staleTime、structuralSharing、suspense、useErrorBoundary其中onSuccess、onError、onSettled三个副作用回调是 react-admin 在透传时单独解构处理并保证稳定引用的通过useEvent包装见 useGetList.ts。而enabled: false可用于延迟请求、staleTime控制数据新鲜度、refetchOnWindowFocus控制窗口聚焦时的自动刷新等这些都是日常高频使用的选项。Query Key 与缓存该 Hook 的 react-query query key 为[resource, getList, { pagination, sort, filter, meta }]这意味着只要resource、pagination、sort、filter、meta中的任何一个发生变化query key 就会变化react-query 会将其视为不同的查询并重新发起请求。同一 key 的查询则共享缓存。这条规则同样被单元测试所验证资源名从posts变为comments时dataProvider.getList会被再次调用见 packages/ra-core/src/dataProvider/useGetList.spec.tsx。基础用法获取记录列表useGetList最常见的应用场景是组件挂载后立即获取列表数据并渲染。import { useGetList } from react-admin; const LatestNews () { const { data, total, isPending, error } useGetList( posts, { pagination: { page: 1, perPage: 10 }, sort: { field: published_at, order: DESC } } ); if (isPending) { return Loading /; } if (error) { return pERROR/p; } return ( h1Latest news/h1 ul {data.map(record li key{record.id}{record.title}/li )} /ul p{data.length} / {total} articles/p / ); };这里data是记录数组每条记录必须有id字段total是数据提供器返回的记录总数isPending为 true 时表示请求尚未完成。返回值详解useGetList的返回值是 TanStack Query 结果与getList响应合并后的对象useGetList.ts字段类型说明dataRecordType[]当前页记录数组totalnumber \| undefined满足条件的记录总数数据提供器不返回时不存在pageInfo{ hasNextPage?: boolean, hasPreviousPage?: boolean }部分分页模式下判断前后页是否存在metaany数据提供器随响应返回的附加元数据isPendingboolean首次请求尚未完成时为 trueisFetchingboolean请求含后台刷新进行中为 trueerrorError \| null请求失败时的错误对象refetch() void手动重新发起请求的函数其余字段—TanStack QueryuseQuery返回的全部属性其中total、pageInfo、meta三个字段的类型定义在 GetListResult 中。请求失败时data可能为undefined因此渲染前务必先处理isPending与error两个分支这与测试中验证的状态流转一致useGetList.spec.tsx。在 react-admin 迭代组件中渲染数据如果要把useGetList的结果交给DataTable、SimpleList、SingleFieldList这类 react-admin 迭代组件渲染你需要先把数据放进一个ListContext。useListHook 就是为此设计的——它接收原始数据生成完整的列表控制器上下文包括分页、排序、选中状态等import { useGetList, useList, ListContextProvider, DataTable, DateField, Pagination } from react-admin; const LatestNews () { const { data, isPending, error } useGetList( posts, { pagination: { page: 1, perPage: 100 } }, ); if (error) { return pERROR/p; } const listContext useList({ data, isPending, perPage: 10, sort: { field: published_at, order: DESC } }); return ( ListContextProvider value{listContext} h1Latest news/h1 DataTable DataTable.Col sourcetitle / DataTable.Col sourcepublished_at field{DateField} / DataTable.NumberCol sourceviews / /DataTable Pagination / /ListContextProvider ); };在这个例子中useGetList一次性拉取全部文章useList在客户端完成每页 10 条的展示、点击列头排序等交互Pagination提供翻页控件。这是服务端只负责取数、客户端负责交互的典型组合。useList的详细参数说明可参考 docs/useList.mdListContext的内容见 docs/useListContext.md。向数据提供器传递额外参数meta 参数如果你需要向数据提供器传递getList标准参数之外的附加信息可以通过第二个参数里的meta字段。例如你的数据提供器支持embed参数来内嵌关联记录const { data, total, isPending, error } useGetList( posts, { pagination: { page: 1, perPage: 10 }, sort: { field: published_at, order: DESC }, // 通过 meta 参数传递附加信息 meta: { embed: [author, category] } } );meta会被原样传给dataProvider.getList()的第二个参数数据提供器可以据此定制请求如拼接 URL 查询串、选择返回字段等。单元测试验证了meta的传递路径useGetList.spec.tsxexpect(dataProvider.getList).toBeCalledWith(posts, { filter: {}, pagination: { page: 1, perPage: 20 }, sort: { field: id, order: DESC }, meta: { hello: world }, signal: undefined, });注意不要把这个meta参数与响应里的meta属性混淆——虽然同名但它们毫不相关。请求meta是你发给数据提供器的响应meta是数据提供器返回给你的。读取响应中的附加元数据如果后端在返回记录之外还附带了一些额外信息可以通过返回值的meta属性访问const { data, total, isPending, error, // 响应中的附加信息 meta } useGetList(posts, { pagination: { page: 1, perPage: 10 }});同样地这个响应meta与请求meta参数无任何关系。它来自getList()响应对象在 useGetList.ts 中通过解构{ data, total, pageInfo, meta }被保留下来。部分分页后端不返回 total 的场景部分后端统计总条数count代价昂贵此时数据提供器可以在响应中省略total改用pageInfo告知是否有上一页/下一页。这一数据提供器约定详见 docs/DataProviderWriting.md响应示例形如// { // data: [ ... ], // pageInfo: { // hasPreviousPage: false, // hasNextPage: true, // } // }useGetList会把pageInfo透传给你据此实现加载更多式的翻页import { useState } from react; import { useGetList } from react-admin; const LatestNews () { const [page, setPage] useState(1); const { data, pageInfo, isPending, error } useGetList( posts, { pagination: { page, perPage: 10 }, sort: { field: published_at, order: DESC } } ); if (isPending) { return Loading /; } if (error) { return pERROR/p; } const { hasNextPage, hasPreviousPage } pageInfo; const getNextPage () setPage(page 1); return ( h1Latest news/h1 ul {data.map(record li key{record.id}{record.title}/li )} /ul {hasNextPage button onClick{getNextPage}More articles/button} / ); };注意此例中pageInfo可能为undefined当数据提供器返回的是total时解构前建议做防御性处理。另外react-admin 的Pagination组件会自动识别pageInfo并渲染对应的分页控件。如果你的目标是向下滚动加载历史数据、旧页面保留在屏幕上类似社交媒体信息流也可以改用useInfiniteGetListHook它会自动拼接已加载的各页数据。获取关联记录优先使用 ReferenceManyField当你想获取与某条记录关联的另一批记录例如一篇文章下的所有评论时建议直接使用ReferenceManyField组件。它会自动处理加载状态并在数据拉取期间显示加载指示器import { ReferenceManyField } from react-admin; const PostComments () { return ( ReferenceManyField referencecomments targetpost_id DataTable DataTable.Col sourcecreated_at field{DateField} / DataTable.Col sourceauthor / DataTable.Col sourcebody / /DataTable /ReferenceManyField ); };它等价于下面这段手动使用useGetListuseRecordContextuseList的代码import { useGetList } from react-admin; const PostComments () { const record useRecordContext(); const { data, isPending, error } useGetList( comments, { filter: { post_id: record.id } } ); if (isPending) { return Loading /; } if (error) { return pERROR/p; } const listContext useList({ data }); return ( ListContextProvider value{listContext} DataTable DataTable.Col sourcecreated_at field{DateField} / DataTable.Col sourceauthor / DataTable.Col sourcebody / /DataTable /ListContextProvider ); };两者效果一致但ReferenceManyField帮你省去了加载状态、上下文组装等样板代码是更推荐的方式。只有当你需要完全自定义取数与交互逻辑时才直接用useGetList手动实现。手动刷新列表useGetList返回的refetch函数可以强制重新发起请求import { useGetList } from react-admin; const LatestNews () { const { data, total, isPending, error, refetch } useGetList(/* ... */); if (isPending) { return Loading /; } if (error) { return pERROR/p; } return ( h1Latest news/h1 ul {data.map(record li key{record.id}{record.title}/li )} /ul p{data.length} / {total} articles/p button onClick{() refetch()}Refresh/button / ); };refetch是 TanStack Query 原生提供的点击按钮即可在任意时刻刷新列表数据。实时更新改用 useGetListLive如果你希望列表在数据变更时自动更新订阅resource/[resource]主题可以改用实时数据 HookuseGetListLive来自react-admin/ra-realtime商业包。把useGetList替换为useGetListLive即可调用方式几乎完全一致-import { useGetList } from react-admin; import { useGetListLive } from react-admin/ra-realtime; const LatestNews () { - const { data, total, isPending, error } useGetList(posts, { const { data, total, isPending, error } useGetListLive(posts, { pagination: { page: 1, perPage: 10 }, sort: { field: published_at, order: DESC }, }); if (isPending) { return Loading /; } if (error) { return pERROR/p; } return ( ul {data.map(item ( li key{item.id}{item.title}/li ))} /ul ); };此后每当有记录被创建、更新或删除data都会自动更新无需手动refetch。TypeScript 泛型支持useGetList接受一个记录类型的泛型参数让data获得完整的类型提示import { useGetList } from react-admin; type Post { id: number; title: string; }; const LatestNews () { const { data: posts, total, isPending, error } useGetListPost( posts, { pagination: { page: 1, perPage: 10 }, sort: { field: published_at, order: DESC } } ); if (isPending) { return Loading /; } if (error) { return pERROR/p; } return ( h1Latest news/h1 ul {/* TypeScript 知道 posts 的类型是 Post[] */} {posts.map(post li key{post.id}{post.title}/li )} /ul p{posts.length} / {total} articles/p / ); };泛型参数约束为RaRecord即至少包含id: Identifier的对象其完整签名见 useGetList.ts。源码级的缓存与取消行为深入源码可以发现useGetList还有两个容易被忽略但非常实用的行为1. 预填充 getOne 缓存请求成功后如果返回的记录数不超过 100 条常量MAX_DATA_LENGTH_TO_CACHE 100useGetList会把每条记录写入对应资源的getOne查询缓存useGetList.ts。这意味着列表页加载过的记录进入详情页时无需重新请求即可立即显示。此行为在 useGetList.spec.tsx 与超过 100 条不预填充useGetList.spec.tsx均有测试覆盖。2. 支持请求取消AbortSignal当数据提供器声明supportAbortSignal true时useGetList会把 TanStack Query 的取消信号透传给getList()useGetList.ts。查询被取消例如组件卸载、key 变化时请求会被中止避免无用的网络开销测试见 useGetList.spec.tsx。3. 副作用回调稳定性onSuccess/onError/onSettled通过useEvent包装始终保持稳定引用不会因闭包问题导致副作用重复触发useGetList.ts。常见问题与建议渲染前必须处理isPending与error请求未完成或失败时data为undefined直接访问data.map会报错先做分支处理是标准姿势。同一资源不同参数会各自缓存query key 包含完整参数翻页、改排序都会生成新查询这也意味着频繁切换筛选条件会产生多个缓存条目可通过staleTime平衡新鲜度与请求次数。服务端取数 vs 客户端交互useGetList只负责从服务端取数分页、排序、选中这类交互逻辑交给useList或ListContext体系二者职责清晰。关联数据优先用ReferenceManyField省去样板代码还能自动获得加载指示器。需要实时更新时考虑useGetListLive商业包或自行结合useSubscribe。useGetList是构建 react-admin 自定义页面、仪表盘、下拉选单数据源的基础设施。理解它的参数语义、缓存规则与源码行为能让你在编写数据密集型界面时少走弯路。相关的配套文档包括DataProviderWriting、useList、useListContext、useInfiniteGetList 与 useGetListLive都可以在本仓库docs/目录下继续深入阅读。【免费下载链接】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),仅供参考

相关新闻

video_player_avfoundation 贡献指南:Pigeon 代码生成文件的更新流程与实战解析

video_player_avfoundation 贡献指南:Pigeon 代码生成文件的更新流程与实战解析

移动开发跨平台 【免费下载链接】plugins Plugins for Flutter maintained by the Flutter team 项目地址: https://gitcode.com/gh_mirrors/pl/plugins 点击查看 免费下载 本指南围绕 Flutter 官方插件仓库中 video_player_avfoundation(video_player …

2026/9/22 18:07:55 阅读更多 →
B站视频总结免费额度难对齐?TaoToken 这样配 Codex 的 config.toml

B站视频总结免费额度难对齐?TaoToken 这样配 Codex 的 config.toml

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/22 18:07:13 阅读更多 →
Claude Code 用 Qwen 报 400?TaoToken 这样配 Base URL

Claude Code 用 Qwen 报 400?TaoToken 这样配 Base URL

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/21 15:55:00 阅读更多 →

最新新闻

淘宝排名靠前技巧揭秘:3个源码级优化点,面试必问的底层逻辑

淘宝排名靠前技巧揭秘:3个源码级优化点,面试必问的底层逻辑

淘宝排名靠前技巧揭秘:3个源码级优化点,面试必问的底层逻辑 官方文档堆砌术语,读完还是不会用?这行混久了都知道,真正的硬核知识往往藏在底层实现里。今天不扯虚的,直接拆解淘宝搜索排名的核心逻辑。很多开发者在面试中被问倒,不是不懂业务,而是不懂…

2026/9/22 18:07:24 阅读更多 →
5分钟吃透Reveal源码,手写实现核心逻辑不踩坑

5分钟吃透Reveal源码,手写实现核心逻辑不踩坑

5分钟吃透Reveal源码,手写实现核心逻辑不踩坑 面试被问“Reveal.js 源码是怎么实现页面切换动画的”,你答得上来吗?别慌,很多后端转全栈的兄弟都栽在这。不是让你背代码,而是得懂那套 手写实现…

2026/9/22 18:07:24 阅读更多 →
3步手写实现quicksort,彻底告别排序崩溃焦虑

3步手写实现quicksort,彻底告别排序崩溃焦虑

3步手写实现quicksort,彻底告别排序崩溃焦虑 上周凌晨两点,线上接口突然超时,CPU飙到100%。翻日志一看,全是 java.lang.OutOfMemoryError 和递归栈溢出的 StackOverflowError…

2026/9/22 18:07:24 阅读更多 →
3招搞定爱在星光里性能瓶颈,图解原理告别StackTrace报错

3招搞定爱在星光里性能瓶颈,图解原理告别StackTrace报错

3招搞定爱在星光里性能瓶颈,图解原理告别StackTrace报错 凌晨两点,服务器报警响了,我抓起电脑一看,CPU飙到95%,日志里全是红色的StackTrace。这种报错一堆看不懂的情况,每个后端开发都经历过。别慌,今天咱们不聊虚的,直接…

2026/9/22 18:07:24 阅读更多 →
3CDAEMON乱码速查手册:从堆栈到源码的性能突围

3CDAEMON乱码速查手册:从堆栈到源码的性能突围

3CDAEMON乱码速查手册:从堆栈到源码的性能突围 面对满屏红色的 StackTrace,是不是感觉脑子瞬间宕机?尤其是当 3CDAEMON 相关的日志输出变成一堆 ? 或 �…

2026/9/22 18:07:24 阅读更多 →
CF人物模型底层逻辑拆解:版本升级API变更保姆级教程

CF人物模型底层逻辑拆解:版本升级API变更保姆级教程

CF人物模型底层逻辑拆解:版本升级API变更保姆级教程 版本升级后 API 全变了?别慌,CF人物系统的底层映射没变。 很多老哥在接手项目时,一跑代码就报错,参数对不上,对象引用丢失。 这篇保姆级教程,带你从内存堆栈角度,彻底搞懂 CF…

2026/9/22 18:06:23 阅读更多 →

日新闻

3台商务办公笔记本实测:手写实现环境配置,告别卡半天

3台商务办公笔记本实测:手写实现环境配置,告别卡半天

3台商务办公笔记本实测:手写实现环境配置,告别卡半天 配置环境就卡半天?别怪机器慢,多半是你没选对工具链。在Java、Go或Python的项目现场, 手写实现…

2026/9/22 0:00:41 阅读更多 →
剑帝加点速查手册:3分钟搞懂核心逻辑

剑帝加点速查手册:3分钟搞懂核心逻辑

剑帝加点速查手册:3分钟搞懂核心逻辑 面试被问原理答不上来,是不是常态?别慌。很多开发者对着 GitHub 开源仓库里的代码发呆,看似简单实则暗藏玄机。今天这份【剑帝加点】速查手册,直接带你拆解核心实现,把面试必考的原理讲透。…

2026/9/22 0:00:41 阅读更多 →
手写实现图片压缩网站核心:搞定WebP转换与质量调优

手写实现图片压缩网站核心:搞定WebP转换与质量调优

手写实现图片压缩网站核心:搞定WebP转换与质量调优 复制来的代码跑不通不知道怎么调?别慌,这种“复制粘贴地狱”在开发圈太常见了。尤其是做 图片压缩网站…

2026/9/22 0:00:41 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/22 4:32:41 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/22 4:38:57 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/22 8:51:04 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/21 15:36:51 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/21 15:36:51 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/22 2:43:42 阅读更多 →