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.