You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 10:33:33