Movatterモバイル変換


[0]ホーム

URL:


TanStack
Tablev8v8
Auto
Log In
Documentation
Framework
Version
Enterprise
Framework
Version
Enterprise

React Example: Pagination Controlled

tsx
import React from 'react'import ReactDOM from 'react-dom/client'import {  keepPreviousData,  QueryClient,  QueryClientProvider,  useQuery,} from '@tanstack/react-query'import './index.css'import {  PaginationState,  useReactTable,  getCoreRowModel,  ColumnDef,  flexRender,} from '@tanstack/react-table'//import { fetchData, Person } from './fetchData'const queryClient = new QueryClient()function App() {  const rerender = React.useReducer(() => ({}), {})[1]  const columns = React.useMemo<ColumnDef<Person>[]>(    () => [      {        header: 'Name',        footer: (props) => props.column.id,        columns: [          {            accessorKey: 'firstName',            cell: (info) => info.getValue(),            footer: (props) => props.column.id,          },          {            accessorFn: (row) => row.lastName,            id: 'lastName',            cell: (info) => info.getValue(),            header: () => <span>Last Name</span>,            footer: (props) => props.column.id,          },        ],      },      {        header: 'Info',        footer: (props) => props.column.id,        columns: [          {            accessorKey: 'age',            header: () => 'Age',            footer: (props) => props.column.id,          },          {            header: 'More Info',            columns: [              {                accessorKey: 'visits',                header: () => <span>Visits</span>,                footer: (props) => props.column.id,              },              {                accessorKey: 'status',                header: 'Status',                footer: (props) => props.column.id,              },              {                accessorKey: 'progress',                header: 'Profile Progress',                footer: (props) => props.column.id,              },            ],          },        ],      },    ],    [],  )  const [pagination, setPagination] = React.useState<PaginationState>({    pageIndex: 0,    pageSize: 10,  })  const dataQuery = useQuery({    queryKey: ['data', pagination],    queryFn: () => fetchData(pagination),    placeholderData: keepPreviousData, // don't have 0 rows flash while changing pages/loading next page  })  const defaultData = React.useMemo(() => [], [])  const table = useReactTable({    data: dataQuery.data?.rows ?? defaultData,    columns,    // pageCount: dataQuery.data?.pageCount ?? -1, //you can now pass in `rowCount` instead of pageCount and `pageCount` will be calculated internally (new in v8.13.0)    rowCount: dataQuery.data?.rowCount, // new in v8.13.0 - alternatively, just pass in `pageCount` directly    state: {      pagination,    },    onPaginationChange: setPagination,    getCoreRowModel: getCoreRowModel(),    manualPagination: true, //we're doing manual "server-side" pagination    // getPaginationRowModel: getPaginationRowModel(), // If only doing manual pagination, you don't need this    debugTable: true,  })  return (    <div className="p-2">      <div className="h-2" />      <table>        <thead>          {table.getHeaderGroups().map((headerGroup) => (            <tr key={headerGroup.id}>              {headerGroup.headers.map((header) => {                return (                  <th key={header.id} colSpan={header.colSpan}>                    {header.isPlaceholder ? null : (                      <div>                        {flexRender(                          header.column.columnDef.header,                          header.getContext(),                        )}                      </div>                    )}                  </th>                )              })}            </tr>          ))}        </thead>        <tbody>          {table.getRowModel().rows.map((row) => {            return (              <tr key={row.id}>                {row.getVisibleCells().map((cell) => {                  return (                    <td key={cell.id}>                      {flexRender(                        cell.column.columnDef.cell,                        cell.getContext(),                      )}                    </td>                  )                })}              </tr>            )          })}        </tbody>      </table>      <div className="h-2" />      <div className="flex items-center gap-2">        <button          className="border rounded p-1"          onClick={() => table.firstPage()}          disabled={!table.getCanPreviousPage()}        >          {'<<'}        </button>        <button          className="border rounded p-1"          onClick={() => table.previousPage()}          disabled={!table.getCanPreviousPage()}        >          {'<'}        </button>        <button          className="border rounded p-1"          onClick={() => table.nextPage()}          disabled={!table.getCanNextPage()}        >          {'>'}        </button>        <button          className="border rounded p-1"          onClick={() => table.lastPage()}          disabled={!table.getCanNextPage()}        >          {'>>'}        </button>        <span className="flex items-center gap-1">          <div>Page</div>          <strong>            {table.getState().pagination.pageIndex + 1} of{' '}            {table.getPageCount().toLocaleString()}          </strong>        </span>        <span className="flex items-center gap-1">          | Go to page:          <input            type="number"            min="1"            max={table.getPageCount()}            defaultValue={table.getState().pagination.pageIndex + 1}            onChange={(e) => {              const page = e.target.value ? Number(e.target.value) - 1 : 0              table.setPageIndex(page)            }}            className="border p-1 rounded w-16"          />        </span>        <select          value={table.getState().pagination.pageSize}          onChange={(e) => {            table.setPageSize(Number(e.target.value))          }}        >          {[10, 20, 30, 40, 50].map((pageSize) => (            <option key={pageSize} value={pageSize}>              Show {pageSize}            </option>          ))}        </select>        {dataQuery.isFetching ? 'Loading...' : null}      </div>      <div>        Showing {table.getRowModel().rows.length.toLocaleString()} of{' '}        {dataQuery.data?.rowCount.toLocaleString()} Rows      </div>      <div>        <button onClick={() => rerender()}>Force Rerender</button>      </div>      <pre>{JSON.stringify(pagination, null, 2)}</pre>    </div>  )}const rootElement = document.getElementById('root')if (!rootElement) throw new Error('Failed to find the root element')ReactDOM.createRoot(rootElement).render(  <React.StrictMode>    <QueryClientProvider client={queryClient}>      <App />    </QueryClientProvider>  </React.StrictMode>,)
import React from 'react'import ReactDOM from 'react-dom/client'import {  keepPreviousData,  QueryClient,  QueryClientProvider,  useQuery,} from '@tanstack/react-query'import './index.css'import {  PaginationState,  useReactTable,  getCoreRowModel,  ColumnDef,  flexRender,} from '@tanstack/react-table'//import { fetchData, Person } from './fetchData'const queryClient = new QueryClient()function App() {  const rerender = React.useReducer(() => ({}), {})[1]  const columns = React.useMemo<ColumnDef<Person>[]>(    () => [      {        header: 'Name',        footer: (props) => props.column.id,        columns: [          {            accessorKey: 'firstName',            cell: (info) => info.getValue(),            footer: (props) => props.column.id,          },          {            accessorFn: (row) => row.lastName,            id: 'lastName',            cell: (info) => info.getValue(),            header: () => <span>Last Name</span>,            footer: (props) => props.column.id,          },        ],      },      {        header: 'Info',        footer: (props) => props.column.id,        columns: [          {            accessorKey: 'age',            header: () => 'Age',            footer: (props) => props.column.id,          },          {            header: 'More Info',            columns: [              {                accessorKey: 'visits',                header: () => <span>Visits</span>,                footer: (props) => props.column.id,              },              {                accessorKey: 'status',                header: 'Status',                footer: (props) => props.column.id,              },              {                accessorKey: 'progress',                header: 'Profile Progress',                footer: (props) => props.column.id,              },            ],          },        ],      },    ],    [],  )  const [pagination, setPagination] = React.useState<PaginationState>({    pageIndex: 0,    pageSize: 10,  })  const dataQuery = useQuery({    queryKey: ['data', pagination],    queryFn: () => fetchData(pagination),    placeholderData: keepPreviousData, // don't have 0 rows flash while changing pages/loading next page  })  const defaultData = React.useMemo(() => [], [])  const table = useReactTable({    data: dataQuery.data?.rows ?? defaultData,    columns,    // pageCount: dataQuery.data?.pageCount ?? -1, //you can now pass in `rowCount` instead of pageCount and `pageCount` will be calculated internally (new in v8.13.0)    rowCount: dataQuery.data?.rowCount, // new in v8.13.0 - alternatively, just pass in `pageCount` directly    state: {      pagination,    },    onPaginationChange: setPagination,    getCoreRowModel: getCoreRowModel(),    manualPagination: true, //we're doing manual "server-side" pagination    // getPaginationRowModel: getPaginationRowModel(), // If only doing manual pagination, you don't need this    debugTable: true,  })  return (    <div className="p-2">      <div className="h-2" />      <table>        <thead>          {table.getHeaderGroups().map((headerGroup) => (            <tr key={headerGroup.id}>              {headerGroup.headers.map((header) => {                return (                  <th key={header.id} colSpan={header.colSpan}>                    {header.isPlaceholder ? null : (                      <div>                        {flexRender(                          header.column.columnDef.header,                          header.getContext(),                        )}                      </div>                    )}                  </th>                )              })}            </tr>          ))}        </thead>        <tbody>          {table.getRowModel().rows.map((row) => {            return (              <tr key={row.id}>                {row.getVisibleCells().map((cell) => {                  return (                    <td key={cell.id}>                      {flexRender(                        cell.column.columnDef.cell,                        cell.getContext(),                      )}                    </td>                  )                })}              </tr>            )          })}        </tbody>      </table>      <div className="h-2" />      <div className="flex items-center gap-2">        <button          className="border rounded p-1"          onClick={() => table.firstPage()}          disabled={!table.getCanPreviousPage()}        >          {'<<'}        </button>        <button          className="border rounded p-1"          onClick={() => table.previousPage()}          disabled={!table.getCanPreviousPage()}        >          {'<'}        </button>        <button          className="border rounded p-1"          onClick={() => table.nextPage()}          disabled={!table.getCanNextPage()}        >          {'>'}        </button>        <button          className="border rounded p-1"          onClick={() => table.lastPage()}          disabled={!table.getCanNextPage()}        >          {'>>'}        </button>        <span className="flex items-center gap-1">          <div>Page</div>          <strong>            {table.getState().pagination.pageIndex + 1} of{' '}            {table.getPageCount().toLocaleString()}          </strong>        </span>        <span className="flex items-center gap-1">          | Go to page:          <input            type="number"            min="1"            max={table.getPageCount()}            defaultValue={table.getState().pagination.pageIndex + 1}            onChange={(e) => {              const page = e.target.value ? Number(e.target.value) - 1 : 0              table.setPageIndex(page)            }}            className="border p-1 rounded w-16"          />        </span>        <select          value={table.getState().pagination.pageSize}          onChange={(e) => {            table.setPageSize(Number(e.target.value))          }}        >          {[10, 20, 30, 40, 50].map((pageSize) => (            <option key={pageSize} value={pageSize}>              Show {pageSize}            </option>          ))}        </select>        {dataQuery.isFetching ? 'Loading...' : null}      </div>      <div>        Showing {table.getRowModel().rows.length.toLocaleString()} of{' '}        {dataQuery.data?.rowCount.toLocaleString()} Rows      </div>      <div>        <button onClick={() => rerender()}>Force Rerender</button>      </div>      <pre>{JSON.stringify(pagination, null, 2)}</pre>    </div>  )}const rootElement = document.getElementById('root')if (!rootElement) throw new Error('Failed to find the root element')ReactDOM.createRoot(rootElement).render(  <React.StrictMode>    <QueryClientProvider client={queryClient}>      <App />    </QueryClientProvider>  </React.StrictMode>,)

    [8]ページ先頭

    ©2009-2025 Movatter.jp