如何使用Refine的useTable钩子从多表获取数据而非useMany?
如何用useTable钩子而非useMany从多个表获取数据?
我想不用useMany,而是用useTable钩子从API的两个或多个表中获取多条记录,已知useTable底层基于useList实现。现在我有customers和orders两个表,能不能让useTable同时获取这两个表的记录?
类型定义
type Customers = { id: number; customer_name: string; customer_contact: string; }; type ServiceType = "Wash" | "Dry" | "Fold" | "Full"; type ServiceStatus = "Undone" | "Washing" | "Drying" | "Folding" | "Done"; type Orders = { id: number; customerId: number; orderDate: Date; orderLoad: number; orderWeight: number; serviceType: ServiceType; orderSoap: number; orderFabcon: number; orderBleach: number; orderNote: string; orderStatus: ServiceStatus; orderIsClaimed: boolean; inventoryId: number | null; payableId: number | null; };
当前useTable代码
const { refineCore: { tableQueryResult: { data: orders }, }, previousPage, nextPage, getCanPreviousPage, getCanNextPage, getHeaderGroups, getRowModel, getColumn, getAllColumns, } = useTable({ columns, onSortingChange: setSorting, onColumnFiltersChange: setColumnFilters, getCoreRowModel: getCoreRowModel(), getPaginationRowModel: getPaginationRowModel(), getSortedRowModel: getSortedRowModel(), getFilteredRowModel: getFilteredRowModel(), onColumnVisibilityChange: setColumnVisibility, onRowSelectionChange: setRowSelection, state: { sorting, columnFilters, columnVisibility, rowSelection, }, });
数据源配置
<Refine dataProvider={dataProvider(supabaseClient)} liveProvider={liveProvider(supabaseClient)} authProvider={authProvider} routerProvider={routerBindings} resources={[ { name: "orders", list: "/orders", create: "/orders/create", edit: "/orders/edit/:id", show: "/orders/show/:id", meta: { canDelete: true, }, }, { name: "customers", list: "/customers", create: "/customers/create", edit: "/customers/edit/:id", show: "/customers/show/:id", meta: { canDelete: true, }, }, { name: "inventory", list: "/inventory", show: "/inventory/show/:id", meta: { canDelete: true, }, }, ]} options={{ syncWithLocation: true, warnWhenUnsavedChanges: true, useNewQueryKeys: true, projectId: "GmM62Q-BMA8wv-2ddnfk", }} > </Refine>
解决方案
useTable本身是为单个资源设计的,无法直接同时请求多个表,但可以通过以下方式实现关联数据的获取:
1. 利用Supabase的JOIN查询扩展请求(推荐)
因为你使用的是Supabase数据提供者,可以在useTable的配置中传递自定义查询参数,让接口一次性返回orders和关联的customers数据:
const { refineCore: { tableQueryResult: { data: ordersWithCustomers }, }, // 其他方法... } = useTable({ columns, // 保留原有排序、分页等配置 refineCoreProps: { meta: { query: { select: ` id, customerId, orderDate, orderLoad, orderWeight, serviceType, orderSoap, orderFabcon, orderBleach, orderNote, orderStatus, orderIsClaimed, inventoryId, payableId, customers(id, customer_name, customer_contact) ` } } } });
这样每条order数据会自动包含对应的customer信息,无需额外调用useMany。
2. 手动关联数据(仅当无法修改查询时使用)
如果无法调整接口查询逻辑,可以在获取orders后,单独查询关联的customer数据并手动合并:
import { useQuery } from '@tanstack/react-query'; import { supabaseClient } from './your-supabase-path'; // 先获取orders列表 const { refineCore: { tableQueryResult: { data: orders, isLoading: ordersLoading }, }, // 其他方法... } = useTable({ columns, // 原有配置 }); // 提取所有需要的customerId const customerIds = orders?.map(order => order.customerId) || []; // 查询对应customer数据 const { data: customers, isLoading: customersLoading } = useQuery({ queryKey: ['customers', customerIds], queryFn: async () => { const { data } = await supabaseClient .from('customers') .select('*') .in('id', customerIds); return data; }, enabled: customerIds.length > 0 && !ordersLoading, }); // 合并orders和customer数据 const ordersWithCustomers = orders?.map(order => ({ ...order, customer: customers?.find(c => c.id === order.customerId) })) || [];
这种方式会多一次请求,且useTable的排序、过滤功能无法作用于customer字段,仅作为备选方案。
内容的提问来源于stack exchange,提问作者Svene
相关产品推荐
相关产品推荐

