Luke
Luke

Reputation: 29

reactjs - React Table Pagination appears to be broken

I am new to using React JS. I have been using react-table to create a component that can filter, sort and paginate some sample data from a JSON file.

Here is the link to the tutorial I have been following: https://www.freakyjolly.com/react-table-tutorial/#.YBfqqZP7SL4

Here is what I am seeing at the moment, the pagination appears to be broken, I am seeing all of the data appear (1000 rows). I am trying to have around 5-10 records showing at a time.

enter image description here

Here is the App.js code.

import React from 'react';
import logo from './logo.svg';
import './App.css';
import FilterTableComponent from './components/filter.pagination.sorting';


function App() {

  return (
    <div className="App">

      <h3>Filter Table using <code>react-table</code></h3>
      <FilterTableComponent />

    </div>
  );
}

export default App;

Here is the filter.paginate.sorting.js code

import React from "react";
import { useTable, useSortBy, usePagination, useFilters, useGlobalFilter, useAsyncDebounce } from 'react-table';
import 'bootstrap/dist/css/bootstrap.min.css';
import JSONDATA from './MOCK_DATA.json';

// Define a default UI for filtering
function GlobalFilter({
    preGlobalFilteredRows,
    globalFilter,
    setGlobalFilter,
}) {
    const count = preGlobalFilteredRows.length
    const [value, setValue] = React.useState(globalFilter)
    const onChange = useAsyncDebounce(value => {
        setGlobalFilter(value || undefined)
    }, 200)

    return (
        <span>
            Search:{' '}
            <input
                className="form-control"
                value={value || ""}
                onChange={e => {
                    setValue(e.target.value);
                    onChange(e.target.value);
                }}
                placeholder={`${count} records...`}
            />
        </span>
    )
}

function DefaultColumnFilter({
    column: { filterValue, preFilteredRows, setFilter },
}) {
    const count = preFilteredRows.length

    return (
        <input
            className="form-control"
            value={filterValue || ''}
            onChange={e => {
                setFilter(e.target.value || undefined)
            }}
            placeholder={`Search ${count} records...`}
        />
    )
}

function Table({ columns, data }) {

    const defaultColumn = React.useMemo(
        () => ({
            // Default Filter UI
            Filter: DefaultColumnFilter,
        }),
        []
    )

    const {
        getTableProps,
        getTableBodyProps,
        headerGroups,
        prepareRow,
        rows,
        page,
        canPreviousPage,
        canNextPage,
        pageOptions,
        pageCount,
        gotoPage,
        nextPage,
        previousPage,
        setPageSize,
        state,
        state: { pageIndex, pageSize },
        preGlobalFilteredRows,
        setGlobalFilter,
    } = useTable(
        {
            columns,
            data,
            defaultColumn,
            initialState: { pageIndex: 0, pageSize: 10 }
        },
        useFilters,
        useGlobalFilter,
        useSortBy,
        usePagination
    )

    return (
        <div>

        <ul className="pagination">
        <li className="page-item" onClick={() => gotoPage(0)} disabled={!canPreviousPage}>
            <a className="page-link">First</a>
        </li>
        <li className="page-item" onClick={() => previousPage()} disabled={!canPreviousPage}>
            <a className="page-link">{'<'}</a>
        </li>
        <li className="page-item" onClick={() => nextPage()} disabled={!canNextPage}>
            <a className="page-link">{'>'}</a>
        </li>
        <li className="page-item" onClick={() => gotoPage(pageCount - 1)} disabled={!canNextPage}>
            <a className="page-link">Last</a>
        </li>
        <li>
            <a className="page-link">
                Page{' '}
                <strong>
                    {pageIndex + 1} of {pageOptions.length}
                </strong>{' '}
            </a>
        </li>
        <li>
            <a className="page-link">
                <input
                    className="form-control"
                    type="number"
                    defaultValue={pageIndex + 1}
                    onChange={e => {
                        const page = e.target.value ? Number(e.target.value) - 1 : 0
                        gotoPage(page)
                    }}
                    style={{ width: '100px', height: '20px' }}
                />
            </a>
        </li>{' '}
        <select
            className="form-control"
            value={pageSize}
            onChange={e => {
                setPageSize(Number(e.target.value))
            }}
            style={{ width: '120px', height: '38px' }}
            >
            {[5, 10, 20, 30, 40, 50].map(pageSize => (
                <option key={pageSize} value={pageSize}>
                    Show {pageSize}
                </option>
            ))}
        </select>
        </ul>
            <GlobalFilter
                preGlobalFilteredRows={preGlobalFilteredRows}
                globalFilter={state.globalFilter}
                setGlobalFilter={setGlobalFilter}
            />
            <pre>
                <code>
                    {JSON.stringify(
                        {
                            pageIndex,
                            pageSize,
                            pageCount,
                            canNextPage,
                            canPreviousPage,
                        },
                        null,
                        2
                    )}
                </code>
            </pre>
            <table className="table" {...getTableProps()}>
                <thead>
                    {headerGroups.map(headerGroup => (
                        <tr {...headerGroup.getHeaderGroupProps()}>
                            {headerGroup.headers.map(column => (
                                <th {...column.getHeaderProps(column.getSortByToggleProps())}>
                                    {column.render('Header')}
                                    {/* Render the columns filter UI */}
                                    <div>{column.canFilter ? column.render('Filter') : null}</div>
                                    <span>
                                        {column.isSorted
                                            ? column.isSortedDesc
                                                ? ' '
                                                : ' '
                                            : ''}
                                    </span>
                                </th>
                            ))}
                        </tr>
                    ))}
                </thead>
                <tbody {...getTableBodyProps()}>
                    {rows.map((row, i) => {
                        prepareRow(row)
                        return (
                            <tr {...row.getRowProps()}>
                                {row.cells.map(cell => {
                                    return <td {...cell.getCellProps()}>{cell.render('Cell')}</td>
                                })}
                            </tr>
                        )
                    })}
                </tbody>
            </table>
            <br />
            <div>Showing the first 20 results of {rows.length} rows</div>
            <div>
                <pre>
                    <code>{JSON.stringify(state.filters, null, 2)}</code>
                </pre>
            </div>
        </div>
    )
}

function FilterTableComponent() {
    const columns = React.useMemo(
        () => [
            {
                Header: 'Name',
                columns: [
                    {
                        Header: 'WIP_ID',
                        accessor: 'WIP_ID',
                    },
                    {
                        Header: 'PRODUCT_SERIAL_NUMBER',
                        accessor: 'PRODUCT_SERIAL_NUMBER'
                    },
                ],
            },
            {
                Header: 'Info',
                columns: [
                    {
                        Header: 'DATE',
                        accessor: 'DATE'
                    },
                    {
                        Header: 'BUCKET_NAME',
                        accessor: 'BUCKET_NAME'
                    },
                    {
                        Header: 'CREATED_TS',
                        accessor: 'CREATED_TS'
                    },
                    {
                        Header: 'FILE_NAME',
                        accessor: 'FILE_NAME'
                    },
                ],
            },
        ],
        []
    )

      const data = JSONDATA
    
    return (
        <Table columns={columns} data={data} />
    )
}

export default FilterTableComponent;

Here is a sample of what the JSON file looks like. Named - MOCK_DATA.json

[{"WIP_ID":"56c97f3e-1c3f-4463-beb2-1af58ebe0db0","PRODUCT_SERIAL_NUMBER":"eab8304c-43e2-4f70-a23a-2db75bf2ce50","DATE":"29/06/2020","BUCKET_NAME":"Bytecard","CREATED_TS":"03/10/2020","FILE_NAME":"elit_proin.tiff"},
{"WIP_ID":"b358a03b-fee6-4957-9017-1de3d9846264","PRODUCT_SERIAL_NUMBER":"b974e89e-9bf9-4329-bc13-1afc3bdd52e0","DATE":"20/12/2020","BUCKET_NAME":"Vagram","CREATED_TS":"25/11/2020","FILE_NAME":"condimentum_id_luctus.mov"},
{"WIP_ID":"9fab6d70-72bc-40ae-a99f-5ae31dc47aec","PRODUCT_SERIAL_NUMBER":"8f9f70ce-b940-486b-a003-5c9db031e54e","DATE":"15/02/2020","BUCKET_NAME":"Domainer","CREATED_TS":"06/05/2020","FILE_NAME":"interdum_in_ante.tiff"},
{"WIP_ID":"5bb40cfb-99dc-413a-8b5f-0b6612e45d34","PRODUCT_SERIAL_NUMBER":"3bab0d2b-5464-4c5d-b1c8-0ba6b32e60fa","DATE":"14/03/2020","BUCKET_NAME":"Lotlux","CREATED_TS":"11/05/2020","FILE_NAME":"diam_nam_tristique.avi"},
{"WIP_ID":"95ae9754-e288-4ceb-b7cf-1b27892e7ace","PRODUCT_SERIAL_NUMBER":"1280dfb1-152d-44fd-aed7-4de8b8b573a6","DATE":"04/04/2020","BUCKET_NAME":"Gembucket","CREATED_TS":"14/10/2020","FILE_NAME":"vehicula.pdf"},

Upvotes: 0

Views: 2126

Answers (1)

ondrovic
ondrovic

Reputation: 1175

I think you need to change this in your tbody

{rows.map((row,i) => 

to

{page.map((row,i) =>

Upvotes: 1

Related Questions