Skip to main content
useTable allows you to get properties that are compatible with table components. All features such as sorting, filtering and pagination come out of the box.

Usage

import { useTable } from "@refinedev/core";

const { tableQuery, sorters, setSorters, filters, setFilters, currentPage, setCurrentPage, pageSize, setPageSize } = useTable({
  resource: "posts",
});

Props

resource
string
Resource name for API data interactions.Default: Resource name that it reads from route
pagination
Pagination
Configuration for pagination.
pagination.currentPage
number
default:"1"
Initial page index.
pagination.pageSize
number
default:"10"
Initial number of items per page.
pagination.mode
'server' | 'off'
default:"server"
Whether to use server side pagination or not.
sorters
object
Sort configuration.
sorters.initial
CrudSort[]
Initial sorter state.
sorters: {
  initial: [
    {
      field: "createdAt",
      order: "desc",
    },
  ],
}
sorters.permanent
CrudSort[]
default:"[]"
Default and unchangeable sorter state.
sorters.mode
'server' | 'off'
default:"server"
Whether to use server side sorting or not.
filters
object
Filter configuration.
filters.initial
CrudFilter[]
Initial filter state.
filters: {
  initial: [
    {
      field: "status",
      operator: "eq",
      value: "published",
    },
  ],
}
filters.permanent
CrudFilter[]
default:"[]"
Default and unchangeable filter state.
filters.defaultBehavior
'merge' | 'replace'
default:"merge"
Default behavior of the setFilters function.
filters.mode
'server' | 'off'
default:"server"
Whether to use server side filter or not.
syncWithLocation
boolean
Sortings, filters, page index and records shown per page are tracked by browser history.Default: Value set in <Refine />. If a custom resource is given, it will be false
queryOptions
UseQueryOptions
react-query’s useQuery options.
meta
MetaQuery
Metadata query for dataProvider.
dataProviderName
string
If there is more than one dataProvider, you should use the dataProviderName that you will use.
successNotification
OpenNotificationParams | false
Notification configuration for successful queries.
errorNotification
OpenNotificationParams | false
Notification configuration for failed queries.
liveMode
'auto' | 'manual' | 'off'
Whether to update data automatically or manually if a related live event is received.
onLiveEvent
(event: LiveEvent) => void
Callback to handle live events.
liveParams
object
Additional params to pass to liveProvider’s subscribe method.
overtimeOptions
object
Loading overtime configuration.
overtimeOptions.interval
number
default:"1000"
Interval in milliseconds.
overtimeOptions.onInterval
(elapsedTime: number) => void
Callback to handle interval events.

Return Values

tableQuery
QueryObserverResult<GetListResponse<TData>, TError>
Result of the react-query’s useQuery.
sorters
CrudSort[]
Current sorting state.
setSorters
(sorter: CrudSort[]) => void
A function to set current sorting state.
filters
CrudFilter[]
Current filters state.
setFilters
(filters: CrudFilter[], behavior?: 'merge' | 'replace') => void
A function to set current filters state. Can also accept a setter function.
// Replace filters
setFilters([{ field: "status", operator: "eq", value: "published" }], "replace");

// Merge filters (default)
setFilters([{ field: "category", operator: "eq", value: "news" }]);

// Using setter function
setFilters((prev) => [...prev, { field: "author", operator: "eq", value: "John" }]);
currentPage
number
Current page index.
setCurrentPage
React.Dispatch<React.SetStateAction<number>>
A function to set the current page index.
pageSize
number
Current page size.
setPageSize
React.Dispatch<React.SetStateAction<number>>
A function to set the current page size.
pageCount
number
Total page count calculated from total and pageSize.
result
object
Simplified data and total values from the query.
result.data
TData[]
Array of data items.
result.total
number | undefined
Total count of data items.
Creates a link for sync with location.
overtime
object
Overtime loading information.
overtime.elapsedTime
number
Elapsed time in milliseconds.

Example

Basic Usage

import { useTable } from "@refinedev/core";

const PostList = () => {
  const { 
    tableQuery,
    sorters,
    setSorters,
    filters,
    setFilters,
    currentPage,
    setCurrentPage,
    pageSize,
    setPageSize,
    pageCount,
    result,
  } = useTable({
    resource: "posts",
    pagination: {
      currentPage: 1,
      pageSize: 10,
    },
    sorters: {
      initial: [
        {
          field: "createdAt",
          order: "desc",
        },
      ],
    },
  });

  if (tableQuery.isLoading) {
    return <div>Loading...</div>;
  }

  return (
    <div>
      <table>
        <thead>
          <tr>
            <th>ID</th>
            <th>Title</th>
            <th>Status</th>
          </tr>
        </thead>
        <tbody>
          {result.data.map((post) => (
            <tr key={post.id}>
              <td>{post.id}</td>
              <td>{post.title}</td>
              <td>{post.status}</td>
            </tr>
          ))}
        </tbody>
      </table>
      
      <div>
        <button 
          onClick={() => setCurrentPage(currentPage - 1)}
          disabled={currentPage === 1}
        >
          Previous
        </button>
        <span>Page {currentPage} of {pageCount}</span>
        <button 
          onClick={() => setCurrentPage(currentPage + 1)}
          disabled={currentPage === pageCount}
        >
          Next
        </button>
      </div>
    </div>
  );
};

With Filters

import { useTable } from "@refinedev/core";

const PostList = () => {
  const { result, filters, setFilters } = useTable({
    resource: "posts",
    filters: {
      initial: [
        {
          field: "status",
          operator: "eq",
          value: "published",
        },
      ],
    },
  });

  return (
    <div>
      <select
        value={filters.find((f) => f.field === "status")?.value}
        onChange={(e) => {
          setFilters([
            {
              field: "status",
              operator: "eq",
              value: e.target.value,
            },
          ]);
        }}
      >
        <option value="published">Published</option>
        <option value="draft">Draft</option>
        <option value="archived">Archived</option>
      </select>
      
      {/* Table content */}
    </div>
  );
};

Build docs developers (and LLMs) love