Pagination in React with REST API

You want what’s shown on the page to reflect the URL in the address bar and vice-versa. So rather than using local component state to control the page number, we will use a page number in the URL as the “single source of truth.”

The Router

When declaring routes in react-router-dom you can use a colon : followed by a variable name to match a dynamic variable. This variable will be available to the component through either props.match.params or the useParams hook.

In our case, we want a variable for pageNumber. The primary route looks like this:

<Route path="/users/page/:pageNumber" component={Users} />

You asked if you should redirect traffic from /users to /users/page/1, and in my opinion we should do the opposite. We can use the Redirect component inside our Switch to handle the redirection.

When routing traffic to the /users page, it is important that this page goes after the one with the page number, because otherwise it will match all of the pages. You could also use the param exact, but you don’t need to as long as the order is right. It’s a general principle of react-router that more specific paths always come first.

Likewise, we want to put our Redirect before the Route which would send those users to the Users page. We will still send them there, but we want to redirect first.

<BrowserRouter>
  <Switch>
    <Redirect from="/users/page/1" to="/users" />
    <Route path="/users/page/:pageNumber" component={Users} />
    <Route path="/users" component={Users} />
    <Route path="/" component={Home} />
  </Switch>
</BrowserRouter>

The Component

Our Users component can figure out which page to render by looking at the pageNumber from props.match.params.pageNumber or the useParams hook. URL params are always a string, so we need to use parseInt before using it in any mathematical operations.

When we are on the first page, there is no pageNumber param, so we need to default to 1 whenever the page number is empty.

const params = useParams();
const pageNumber = params.pageNumber ? parseInt(params.pageNumber, 10) : 1;

You would base your API call on the pageNumber. You can use string literal syntax to compose the right URL string.

axios.get(`http://127.0.0.1:5000/User/page?start=${1 + limit * (pageNumber - 1)}&limit=${limit}`);

The Previous and Next links should be shown conditionally, since there is no previous page from page 1. You can use the results of your API call to see if there is a next page.

const hasPrevious = pageNumber > 1;
const hasNext = !!state.next;

We implement those links using the Link component from react-router-dom. The to param takes the path that we want to link to. We will add and subtract from our current pageNumber.

<div>
   {hasPrevious && (
        <Link to={`/users/page/${pageNumber - 1}`}>Previous</Link>
    )}
    {hasNext && (
       <Link to={`/users/page/${pageNumber + 1}`}>Next</Link>
    )}
</div>

Obviously I don’t have access to your API, but I created a little demo to make sure that I got the pagination right.

For more information on the specific components used, make sure to check out the React Router Docs.

CLICK HERE to find out more related problems solutions.

Leave a Comment

Your email address will not be published.

Scroll to Top