In this step, we'll add in the heart of pagination functionality. We'll add a new state property to track the dynamic rows, and a few more handler functions to facilitate updating the various state properties based off of user interactions.
Task
1) Create a new state property to represent our dynamic rows, call it "rows". Set the initial value to the defaultRows constant that you defined earlier. Place this code just above the handlePerPageSelect function you added in the last step.
const [rows, setRows] = React.useState(defaultRows);
2) Locate the code that sets the rows for the table (rows={defaultRows}
), and update it to reference the new rows state property you just created.
rows={rows}
Note: the itemCount prop will still reference the defaultRows constant as itemCount needs to be aware of the total number of rows in the entire dataset, not the number of rows that's being shown at a given time.
3) Add a function "updateList" just above handlePerPageSelect to handle setting the rows based on when the numPerPage state property changes.
const updateList = value => {
setCurrentPage(value);
const beginMark = (value - 1) * numPerPage;
const endMark = beginMark + numPerPage;
let newRows = defaultRows.slice(beginMark, endMark);
setRows(newRows);
};
4) Inside the handlePerPageSelect handler, make a call to updateList and pass it the currentPage state property.
updateList(currentPage);
5) Add a useEffect hook inside your component that we'll teach to only run when certain properties change. This effects hook will ultimately ensure numPerPage
and rows
stay in sync. Inside this effect, make a call to handlePerPageSelect, pass null for the first param (event) and pass numPerPage as the second param. Place this code just above the return statement in your App component.
React.useEffect(() => {
handlePerPageSelect(null, numPerPage);
}, []);
6) Locate the empty dependency array for the useEffect hook you just created, it's the second parameter ([]
) that was passed to useEffect. This second parameter to useEffect represents an array of the function's dependencies.
7) Specify numPerPage and handlePerPageSelect as effect dependencies by listing them in the dependency array from the previous step. Replace the empty array with the following;
[numPerPage, handlePerPageSelect]
8) Locate the <Pagination>
component and set the onSetPage
prop to an inline arrow function, and within this function make a call to updateList, pass updateList the value you receive as a second parameter.
onSetPage={(_evt, value) => {
updateList(value);
}}
At this point, you should see basic pagination in place. Nice! There is some important cleanup left to do, which we'll get to in the next step.
Your rendered output should look something like the screenshot below:

Your component implementation should look something like the following:
import * as React from "react";
import "@patternfly/react-core/dist/styles/base.css";
import { Table, TableHeader, TableBody } from "@patternfly/react-table";
import { Pagination } from "@patternfly/react-core";
import { columns, defaultRows } from "./data";
const App = () => {
const [numPerPage, setNumPerPage] = React.useState(2);
const [currentPage, setCurrentPage] = React.useState(1);
const [rows, setRows] = React.useState(defaultRows);
const updateList = value => {
setCurrentPage(value);
const beginMark = (value - 1) * numPerPage;
const endMark = beginMark + numPerPage;
let newRows = defaultRows.slice(beginMark, endMark);
setRows(newRows);
};
const handlePerPageSelect = (event, value) => {
updateList(currentPage);
setNumPerPage(value);
};
React.useEffect(() => {
handlePerPageSelect(null, numPerPage);
}, [numPerPage, handlePerPageSelect]);
return (
<React.Fragment>
<Pagination
onSetPage={(_evt, value) => {
updateList(value);
}}
onPerPageSelect={handlePerPageSelect}
perPageOptions={[{ title: "2", value: 2 }, { title: "3", value: 3 }]}
page={currentPage}
perPage={numPerPage}
itemCount={defaultRows.length}
/>
<Table
caption="Patternfly React Table"
cells={columns}
rows={rows}
variant="compact"
>
<TableHeader />
<TableBody />
</Table>
</React.Fragment>
);
};
export default App;