Refine v3 useList 排序实战:通过 config.sort 动态触发服务端排序请求
Refine v3 useList 排序实战通过 config.sort 动态触发服务端排序请求【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refineRefine v3 的数据 HookuseList是 TanStack QueryuseQuery的扩展负责从指定resource拉取列表数据并将分页、排序、过滤等配置透传给dataProvider的getList方法。本文以 v3 官方文档中useList的排序SortingLive Preview 为例完整讲解config.sort的用法、排序参数变化自动触发新请求的机制并结合开源仓库中useList的源码实现说明其底层原理与参数流转路径。读完本文你将能够在任意 Refine 页面中实现可切换升/降序的列表、理解排序参数如何进入查询缓存键并驱动重新请求、以及掌握useList各配置项的完整参数表。一、排序示例完整代码排序是useList的核心能力之一。下面这段代码完整来自仓库中的排序 Live Preview 演示文件 sorting-live-preview.md它展示了一个可点击切换升/降序的产品列表组件import { useState } from react; import { useList, HttpError } from pankod/refine-core; interface IProduct { id: number; name: string; material: string; } const ProductList: React.FC () { const [order, setOrder] useStateasc | desc(asc); const { data, isLoading, isError } useListIProduct, HttpError({ resource: products, config: { sort: [ { field: name, order, }, ], }, }); const products data?.data ?? []; if (isLoading) { return divLoading.../div; } if (isError) { return divSomething went wrong!/div; } return ( div button onClick{() setOrder((prev) (prev asc ? desc : asc)) } toggle sort /button ul {products.map((product) ( li key{product.id} h4 {product.name} - ({product.material}) /h4 /li ))} /ul /div ); };演示文件同时将该组件注册为products资源的list页面并渲染 Headless 版Refine骨架setRefineProps({ resources: [ { name: products, list: ProductList, }, ], }); render(RefineHeadlessDemo /);代码要点拆解useState持有排序方向order的取值只能是asc | desc字面量联合与sort配置项中order字段的类型严格一致。sort是数组结构config.sort接收Array{ field: string; order: asc | desc }数组顺序即多字段排序的优先级上面的示例按name字段单字段排序。排序方向是响应式的点击toggle sort按钮更新order状态后useList收到新的sort参数自动发起一次新的getList请求。二、useList的排序工作机制排序部分在 v3 官方文档 useList/index.md 中的原始描述是useList支持排序特性传入sort属性即可启用排序useList会将sort属性透传给dataProvider的getList方法处理动态修改sort属性会触发一次新请求。这句话背后有两条机制在支撑1. 查询键Query Key由参数生成参数变了缓存键就变文档明确说明useList使用一个由传入属性生成的 query key 来缓存数据可以通过 TanStack Query devtools 查看该 key。从当前仓库packages/core中useList的源码结构可以印证这一机制查询键由dataProviderName resource action(list) params逐段构建其中 params 包含了 filters、pagination、sorters 等参数见 useList.ts。由于排序参数是缓存键的组成部分order从asc变为desc时缓存键随之改变TanStack Query 判定为新查询从而自动重新执行查询函数——这就是示例中点按钮即刷新列表的底层原因无需手动调用 refetch。2.queryFn将排序参数原样交给dataProvider.getList查询函数的实现就是把resource、pagination、filters、排序参数与meta一起传给getList见 useList.ts。具体排序参数如何转成 URL query string例如?sortnameorderasc完全取决于所用dataProvider的实现——resource通常被当作 API 端点路径处理方式完全取决于getList方法内部对resource的处理逻辑文档原话。仓库中refinedev/rest包内置了 nestjsx-crud、simple-rest、strapi-v4 等多种 provider各自的options文件定义了排序参数的默认转换策略如 nestjsx-crud.options.ts并提供 handleSort 等工具函数及对应测试handleSort.spec.ts可以按 provider 逐一查看排序参数的落地格式。三、config参数完整说明v3 APIv3 文档在 Config Parameters 一节给出了UseListConfig的完整接口定义这是使用useList时最重要的参考契约interface UseListConfig { hasPagination?: boolean; pagination?: { current?: number; pageSize?: number; }; sort?: Array{ field: string; order: asc | desc; }; filters?: Array{ field: string; operator: CrudOperators; value: any; }; }各配置项的用途配置项说明示例config.sort排序参数透传给getList用于向 API 发送排序 query 参数sort: [{ field: title, order: asc }]config.filters过滤参数向 API 发送过滤 query 参数遵循CrudFilters接口filters: [{ field: title, operator: contains, value: Foo }]config.pagination.current当前页码pagination: { current: 2 }config.pagination.pageSize每页条数pagination: { pageSize: 20 }config.hasPagination是否启用服务端分页不启用则一次性取回数据hasPagination: false三个参数sort、filters、pagination遵循同一套响应式规则动态修改任意一个都会触发新的getList请求因为它们是查询缓存键的组成部分。useList除config外还支持以下顶层属性均为可选属性说明示例resource必填资源名透传给getList通常被用作 API 端点路径resource: categoriesdataProviderName存在多个 dataProvider 时指定使用哪一个dataProviderName: second-data-providerqueryOptions透传给useQuery的额外选项queryOptions: { retry: 3 }metaData向 dataProvider 方法传递附加信息如请求头或用于以普通 JS 对象生成 GraphQL 查询metaData: { headers: { x-meta-data: true } }successNotification需要NotificationProvider数据拉取成功后调用其open展示成功通知可自定义返回{ message, description, type }见下方示例errorNotification需要NotificationProvider拉取失败时展示错误通知可自定义见下方示例liveMode需要LiveProvider取auto或manual决定收到实时事件时是否自动更新数据liveMode: autoonLiveEvent需要LiveProvider订阅事件到达时的回调onLiveEvent: (event) console.log(event)liveParams需要LiveProvider透传给liveProvider.subscribe的参数—通知回调示例useList({ successNotification: (data, values, resource) { return { message: ${data.title} Successfully fetched., description: Success with no errors, type: success, }; }, });四、类型参数与返回值类型参数v3 API类型参数说明类型默认值TData查询结果数据类型继承BaseRecordBaseRecordBaseRecordTError自定义错误对象类型继承HttpErrorHttpErrorHttpErrorTData即示例中useListIProduct, HttpError的第一个参数用来让data.data获得IProduct[]这样的精确类型推导。返回值useList直接返回 TanStack QueryuseQuery的QueryObserverResult{ data: TData[]; total: number }, TError因此data、isLoading、isError、refetch等标准字段都可直接使用示例中取data?.data得到记录数组、data?.total得到总数服务端分页场景下。五、版本演进提示v3 到当前 main 分支的 API 差异需要注意本文代码与参数表对应的是v3 版本 API包名pankod/refine-core文档路径位于 version-3.xx.xx。当前仓库packages/core的主干源码已是后续大版本的实现从源码结构看有两处明显的 API 演进sort更名为sorters主分支的UseListProps中参数名为sorters?: CrudSort[]且不再是config的子字段而是与filters、pagination平级的顶层参数见 useList.ts。同理metaData对应为meta。返回值结构变化主分支useList不再直接平铺useQuery结果而是返回{ query, result, overtime }结构其中result.data为记录数组内部用EMPTY_ARRAY兜底空数据、result.total为总数query保留完整的useQuery返回值见 useList.ts 与 useList.ts。如果你正在使用 v3 项目请以本文的config.sort写法为准若阅读主分支源码或测试useList.spec.tsx时看到sorters两者语义一致只是命名与层级调整。排序参数变化即触发新请求的核心机制——参数参与 query key 生成、queryFn透传给getList——在两个版本中保持一致。六、小结useList的排序通过config.sort: [{ field, order }]声明order仅支持asc | desc数组顺序决定多字段排序优先级排序参数是查询缓存键的组成部分用useState动态修改order即可让 TanStack Query 自动发起新的getList请求无需手动 refetch排序参数如何落地为 URL query 参数由各dataProvider的getList实现决定refinedev/rest内置 provider 提供了可查阅的默认转换实现与测试useList同时支持过滤、分页、metaData 透传、成功/失败通知与实时订阅等配置类型参数TData/TError与useQuery返回值保证了完整的类型推导能力。【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考