wise-white
wise-white5mo ago

I don't understand how useTable works

What action does this hook call? Does it even use my dataProvider? If not, what hook can I use that actually uses my dataProvider without making it a hassle to deal with pagination?
2 Replies
kapa.ai
kapa.ai5mo ago
Hi @chrystiansilva. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- The useTable hook in Refine is designed to fetch data according to the sorter, filter, and pagination states. It uses the useList hook under the hood for fetching the data. It's designed to be headless, meaning it expects you to handle the UI. However, Refine offers seamless integration with several popular UI libraries, simplifying the use of their table components (source (https://refine.dev/docs/data/hooks/use-table/)). When you use the useTable hook, it calls the getList method from your dataProvider under the hood. The dataProvider is a property that allows communication with the API. All the data fetching and mutations are done through this property (source (https://refine.dev/blog/build-internal-tools-using-low-code-with-refine#communicate-with-the-api)). Here's an example of how you might use the useTable hook:
import { useTable } from "@refinedev/core";

export const ProductTable: React.FC = () => {
const { tableQueryResult, pageCount, pageSize, current, setCurrent } = useTable<IProduct>({
resource: "products",
pagination: {
current: 1,
pageSize: 10,
},
});
const posts = tableQueryResult?.data?.data ?? [];

if (tableQueryResult?.isLoading) {
return <div>Loading...</div>;
}
// Rest of your component
}
import { useTable } from "@refinedev/core";

export const ProductTable: React.FC = () => {
const { tableQueryResult, pageCount, pageSize, current, setCurrent } = useTable<IProduct>({
resource: "products",
pagination: {
current: 1,
pageSize: 10,
},
});
const posts = tableQueryResult?.data?.data ?? [];

if (tableQueryResult?.isLoading) {
return <div>Loading...</div>;
}
// Rest of your component
}
(source (https://refine.dev/docs/guides-concepts/tables#basic-usage)) In this example, useTable is used to fetch data from the "products" resource with a specified pagination state. The fetched data is then stored in the posts variable. If you want to use a hook that uses your dataProvider and handles pagination, you can use the useList hook. It fetches data according to the pagination, sorter, and filter states, and it uses your dataProvider to do so (source (https://refine.dev/docs/data/hooks/use-list/)). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
wise-white
wise-white5mo ago
"When you use the useTable hook, it calls the getList method from your dataProvider under the hood." I'm not sure about this. I'm running 4.46.1, here's my mocked data provider:
export const mockDataProvider = (
apiUrl: string,
httpClient: AxiosInstance = axiosInstance
): Omit<
Required<DataProvider>,
"createMany" | "updateMany" | "deleteMany"
> => ({
getList: async ({ resource, pagination, filters, sorters, meta }) => {
console.log("@ getList");
const mock = RESOURCE_DATA_PROVIDER_MOCKS[resource];
if (!mock) {
throw new Error(`No mock found for resource ${resource}`);
}

return {
data: mock.getList,
total: mock.getList.length,
};
},
// other stuff
})
export const mockDataProvider = (
apiUrl: string,
httpClient: AxiosInstance = axiosInstance
): Omit<
Required<DataProvider>,
"createMany" | "updateMany" | "deleteMany"
> => ({
getList: async ({ resource, pagination, filters, sorters, meta }) => {
console.log("@ getList");
const mock = RESOURCE_DATA_PROVIDER_MOCKS[resource];
if (!mock) {
throw new Error(`No mock found for resource ${resource}`);
}

return {
data: mock.getList,
total: mock.getList.length,
};
},
// other stuff
})
When accessing my page, the "@ getList" console.log is not seen anywhere. Here's the code to my page:
export default function StoreUserList() {
const { tableProps } = useTable({
syncWithLocation: true,
});

return (
<List>
<Table {...tableProps} rowKey="id">
<Table.Column dataIndex="id" title="Id" />
<Table.Column dataIndex="name" title="Name" />
<Table.Column
title="Actions"
dataIndex="actions"
render={(_, record: BaseRecord) => (
<Space>
<EditButton hideText size="small" recordItemId={record.id} />
<ShowButton hideText size="small" recordItemId={record.id} />
</Space>
)}
/>
</Table>
</List>
);
}
export default function StoreUserList() {
const { tableProps } = useTable({
syncWithLocation: true,
});

return (
<List>
<Table {...tableProps} rowKey="id">
<Table.Column dataIndex="id" title="Id" />
<Table.Column dataIndex="name" title="Name" />
<Table.Column
title="Actions"
dataIndex="actions"
render={(_, record: BaseRecord) => (
<Space>
<EditButton hideText size="small" recordItemId={record.id} />
<ShowButton hideText size="small" recordItemId={record.id} />
</Space>
)}
/>
</Table>
</List>
);
}
Changing the logic in my dataProvider's getList method to always return an empty array did in fact make the table show no records, but I was very confused as to why I couldn't see the logs in my console.