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);
//