I have data which I populated from the network tab of an ecommerce website, if I have the data of 20 pages in one "data.json" file, how do I make it such so that one page displays first 20 items, the next page shows the next 20 items?
Asked
Active
Viewed 1,849 times
1
-
Keep track of a `page` and `rowsPerPage` variable. Slice the data array like this: `data.slice((page - 1) * rowsPerPage, page * rowsPerPage)`. If the number of rows is constant, you don't need a state variable, and can just hardcode it. – Arno van Liere Dec 19 '21 at 11:49
-
1Does this answer your question? [How to implement pagination in React](https://stackoverflow.com/questions/40232847/how-to-implement-pagination-in-react) – Nikita Skrebets Dec 25 '21 at 20:16
1 Answers
0
First I would create some IIFE curried function which first loads data.json
file and returns function which paginates data.
const getPagedItems = (() => {
const allItemsPromise = loadDataJson();
return (page, pageSize) => {
return allItemsPromise.then(allItems => {
const it = page * pageSize;
const items = allItems.slice(it, it + pageSize);
return {
items,
totalCount: allItems.length
}
});
}
})();
As for the component structure, I would create List component for rendering items and Paginator component for traversing items, setting items per page etc.
Or import some 3rd part component which handles these things like MUI React Table
<Page>
<List items={items} />
<Paginator
page={page}
totalPages={totalPages}
itemsPerPage={itemsPerPage}
onSelectPage={onSelectPage}
onSelectItemsPerPage={onSelectItemsPerPage} />
</Page>
Example
const { useState, useEffect } = React;
const itemsPerPageList = [5, 10];
// data.json
const getAllItems = () => Promise.resolve(Array(23).fill(0).map((pr, index) => ({
id: index,
name: `Item ${index + 1}`
})));
const getPagedItems = (() => {
const allItemsPromise = getAllItems();
return (page, pageSize) => {
return allItemsPromise.then(allItems => {
const it = page * pageSize;
const items = allItems.slice(it, it + pageSize);
return {
items,
totalCount: allItems.length
}
});
}
})();
const List = ({
items,
}) => {
return <div>
{items.map(pr => <div key={pr.id}>{pr.name}</div>)}
</div>
}
const Paginator = ({
itemsPerPage,
page,
totalPages,
onSelectPage,
onSelectItemsPerPage
}) => {
const _onSelectPage = (event) => {
const page = Number(event.currentTarget.dataset.page);
onSelectPage(page);
}
const _onSelectItemsPerPage = (event) => {
const page = Number(event.currentTarget.value);
onSelectItemsPerPage(page);
}
return <div className="paginator">
<div>Items per page</div>
<select onChange={_onSelectItemsPerPage}>
{itemsPerPageList.map(pr => <option key={pr} value={pr}>{pr}</option>)}
</select>
<div>Page {page} of {totalPages}</div>
<button
data-page={page - 1}
disabled={!page}
onClick={_onSelectPage}
type="button">Previous</button>
<button
data-page={page + 1}
disabled={page === totalPages}
onClick={_onSelectPage}
type="button">Next</button>
</div>
}
const App = () => {
const [{
items,
page,
totalPages,
itemsPerPage
}, setState] = useState({
items: [],
page: 0,
totalPages,
itemsPerPage: 5,
});
useEffect(() => {
let unmounted = false;
getPagedItems(page, itemsPerPage).then(result => {
const totalPages = Math.floor(result.totalCount / itemsPerPage);
if(unmounted) {
return;
}
setState(state => ({
...state,
items: result.items,
totalPages,
}));
});
return () => unmounted = true;
}, []);
const onSelectPage = (page) => {
getPagedItems(page, itemsPerPage)
.then(result => {
setState(state => ({
...state,
page,
items: result.items,
}));
})
}
const onSelectItemsPerPage = (itemsPerPage) => {
const page = 0;
getPagedItems(page, itemsPerPage)
.then(result => {
const totalPages = Math.floor(result.totalCount / itemsPerPage);
setState(state => ({
...state,
page,
items: result.items,
itemsPerPage,
totalPages,
}));
})
}
return <div>
<List items={items}/>
<Paginator
page={page}
totalPages={totalPages}
itemsPerPage={itemsPerPage}
onSelectPage={onSelectPage}
onSelectItemsPerPage={onSelectItemsPerPage}
/>
</div>
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
.paginator {
display: flex;
justify-content: space-around;
}
<script src="https://unpkg.com/react/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<div id="root"></div>

Józef Podlecki
- 10,453
- 5
- 24
- 50