Pagination issue with fetching data in React using useState and useEffect
I'm working on a React application where I have a UserList component that displays a list of users fetched from a backend API. I'm implementing a pagination system using the useState and useEffect hooks, and I'm facing an issue with fetching the data based on the selected page number and page size.
Here's a simplified version of my code:
import { Link, useNavigate } from 'react-router-dom';
import React, { useEffect, useState } from 'react';
import UiContent from "../../../Components/Common/UiContent";
import { Button, ButtonGroup, Card, CardBody, Col, Container, Row } from "reactstrap";
import BreadCrumb from "../../../Components/Common/BreadCrumb";
import { _, Grid } from "gridjs-react";
import userService from "../../../helpers/user.service";
const UserList = () => {
const navigate = useNavigate();
const [state, setState] = useState({ users: [], isLoading: true, currentPage: 0, pageSize: 5, totalRecords: 0 });
useEffect(() => {
fetchUserList(state.currentPage, state.pageSize);
}, []);
const fetchUserList = async (page, limit) => {
try {
const response = await userService.getUserList(page, limit);
console.log(response);
const { userDtoList, totalRecords } = response.data;
setState(prevState => ({ ...prevState, users: userDtoList, totalRecords, isLoading: false }));
} catch (error) {
console.log(error);
}
};
const removeUser = async (id) => {
try {
await userService.deleteUser(id);
setState(prevState => ({
...prevState,
users: prevState.users.filter(user => user.id !== id),
isLoading: false
}));
} catch (error) {
console.log(error);
}
};
const editUser = (id) => {
navigate(`/users/${id}`);
};
const onPageChange = (pageNumber) => {
setState(prevState => ({ ...prevState, currentPage: pageNumber }));
fetchUserList(pageNumber, state.pageSize);
};
const onPageSizeChange = (pageSize) => {
setState(prevState => ({ ...prevState, pageSize, currentPage: 1 }));
fetchUserList(1, pageSize);
};
const { users, isLoading, currentPage, pageSize, totalRecords } = state;
if (isLoading) {
return <p>Loading...</p>;
}
console.log(users);
console.log(totalRecords);
if (!users) {
return <p>No users found.</p>;
}
const gridColumns = [
{
name: 'ID',
formatter: (cell) => _(<span className="fw-semibold">{cell}</span>)
},
"firstName",
"lastName",
{
name: 'Email',
formatter: (cell) => _(<a href="/#"> {cell} </a>)
},
{
name: 'Actions',
width: '120px',
formatter: (cell, row) => _(
<div>
<ButtonGroup>
<Button
size="sm"
color="primary"
onClick={() => editUser(row.cells[0].data)}>
Edit
</Button>
<Button
size="sm"
color="danger"
onClick={() => removeUser(row.cells[0].data)}>
Delete
</Button>
</ButtonGroup>
</div>
)
},
];
const gridData = users ? users.map(user => [
user.id,
user.firstName,
user.lastName,
user.email,
]) : [];
return (
<React.Fragment>
<UiContent />
<div className="page-content">
<Container fluid>
<BreadCrumb title="List" pageTitle="Users" />
<Row>
<Col lg={12}>
<Card>
<Link to="/users/new">
<Button color="success" title="Add Users">
Add User
</Button>
</Link>
<CardBody>
<div id="table-gridjs">
<Grid
columns={gridColumns}
/*data={gridData}*/
server= {{
url: 'http://localhost:8081/api/user/list/0/5',
then: data => data.userDtoList,
total: data => data.totalRecords
}}
search={true}
sort={true}
fixedHeader={true}
pagination={{
enabled: true,
limit: pageSize,
onChange: onPageChange,
onPageSizeChange: onPageSizeChange,
total: totalRecords,
current: currentPage,
server: {
url: (prev, page, limit) => `${prev}?limit=${limit}&offset=${page}`
}
}}
/>
</div>
</CardBody>
</Card>
</Col>
</Row>
</Container>
</div>
</React.Fragment>
);
};
export default UserList;
The issue I'm facing is that when I change the page or page size, the data is not being fetched correctly. The initial data is fetched correctly on component mount, but subsequent requests don't update the user list.
I suspect that there might be an issue with the useEffect dependency array or the way I'm updating the state in the fetchUserList function.
I've tried debugging the code and logging the values of currentPage, pageSize, and totalRecords, and they seem to be updated correctly when interacting with the pagination component. However, the fetchUserList function is not fetching the correct data.
It's worth noting that when I use the server prop of Grid.js, the pagination works correctly. However, in my fetchUserList function, I need to include a token for authentication purposes, which is why I want to send the request from the userService module.
Can someone please guide me on how to properly implement the pagination system using the useState and useEffect hooks, while also incorporating the token authentication in the fetchUserList function? Specifically, how can I ensure that the data is fetched correctly when the page number or page size changes, and how can I include the token in the request?