A code snippet for a React component with a simple pagination.
When user clicks prev/next button, update query string (page, pageSize) via
navigate()
- this URL update does not reload the page.At first load and when
useEffect([location.search])
seeslocation.search
(query string) changed,populateMyList()
runs.When
populateMyList()
fetches data,setMyList()
andsetLoading()
are called. ThosesetState
calls trigger a render to reflect the new data.
import React, { useState, useEffect } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';
export function MyList() {
//this stores and tracks our data
const [myList, setMyList] = useState({ totalCount: 0, data: [] });
const [loading, setLoading] = useState(true);
//we need this to get and manipulate our querystring (page, pageSize)
const location = useLocation();
const navigate = useNavigate();
const queryParams = new URLSearchParams(location.search);
//set default page and pageSize if not in the URL
const page = Number(queryParams.get('page')) || 1;
const pageSize = Number(queryParams.get('pageSize')) || 10;
const dataUrl = new URL('mylistdata', window.location.origin);
dataUrl.searchParams.append('page', page);
dataUrl.searchParams.append('pageSize', pageSize);
//function to fetch data from the server
const populateMyList = async () => {
const response = await fetch(dataUrl);
const data = await response.json();
setMyList(data);
setLoading(false);
};
//calls populate when querystring changed (page, pageSize)
useEffect(() => {
populateMyList();
}, [location.search]);
//event handler to move to the previous page
const goToPrevPage = () => {
const params = new URLSearchParams();
if(page > 1) {
params.set('page', page - 1);
params.set('pageSize', pageSize);
navigate(`?${params.toString()}`);
}
};
//event handler to move to the next page
const goToNextPage = () => {
const params = new URLSearchParams();
params.set('page', page + 1);
params.set('pageSize', pageSize);
navigate(`?${params.toString()}`);
};
//this will be used to determine if we can go to the previous or next page
const hasPrevPage = page > 1;
const hasNextPage = myList.totalCount > page * pageSize;
//function for rendering the actual list
const renderMyList = (list) => (
<ul>
{list.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ul>
);
return (
<div>
<h1 id="listLabel">My List</h1>
{loading ? <p><em>Loading...</em>p> : renderMyList(myList.data)}
<button onClick={goToPrevPage} disabled={!hasPrevPage}>Prev</button>
<button onClick={goToNextPage} disabled={!hasNextPage}>Next</button>
</div>
);
}