So I'm rendering filtered products, and now I want to create pagination. It is working but I need to click a page number first before it shows up. I already included a loading state, but it's not working properly.
My data is coming from the backend MongoDB
const ProductList = ({products, category}) => {
const [filteredProducts, setFilteredProducts] = useState([])
const [loading, setLoading] = useState(true)
useEffect(() =>{
const isAvailable = products.filter((product) => product.quantity !== 0 )
setFilteredProducts(isAvailable)
setLoading(false)
},[setFilteredProducts, category,products])
const firstIndex = 0
const [pageSize, setPageSize] = useState(5)
const [page, setPage] = useState(1)
const [data,setData] = useState(filteredProducts.slice(firstIndex, pageSize))
useEffect(() =>{
setData(filteredProducts.slice(0, pageSize))
setLoading(false)
},[pageSize])
const handleChange = (event, value) => {
setPage(value);
setData(filteredProducts.slice(firstIndex pageSize * (value - 1), pageSize * value));
};
return (
<>
{loading ?
<BeatLoader
color="#36d7b7"
loading={loading}
size={50}
aria-label="Loading Spinner"
data-testid="loader"
/>
:
(
<Box sx={{backgroundColor: '#f5f5f5', display:'flex', marginTop:2}}>
<Container maxWidth="xl">
<Typography sx={{textAlign: 'center', paddingY: '20px', fontWeight: 700, color: '#212121', typography: {xs: "h6", md: "h4"}}}>Products</Typography>
<Box sx={{display: 'flex', alignItems:'center',justifyContent: 'space-evenly', flexWrap: 'wrap', gap: '10px'}}>
{data.map((product) => (
<ProductItem key={product._id} product={product} />
))}
</Box>
<Pagination
sx={{display: 'flex', alignItems:'center',justifyContent:'center',margin: 4}}
size="large"
count={Math.ceil(filteredProducts.length/pageSize)}
page={page}
onChange={handleChange}
/>
</Container>
</Box>
)
}
</>
)
}
export default ProductList
CodePudding user response:
It looks like the second useEffect is using the value of filteredProducts but not having it in the dependencies array, so it could not update data when it is ready or if it changes.
This seems to be the reason data could only be updated with the handleChange event.
To fix this, try add filteredProducts to the dependencies array:
useEffect(() => {
setData(filteredProducts.slice(0, pageSize));
setLoading(false);
// 

