I am getting an array of 5k objects from jsonplaceholder (photos endpoint). And I want to sort it by albumId using a Material-UI select. So the problem is state is not being displayed properly. When I choose 'desc' options my items grid is not being updated, but when I drop the sorting state to it's initial value, the rerender happens and I am getting a sorted by 'desc' order list.
API link: json placeholder photos JSON
const handleChangeSort = (e: SelectChangeEvent) => {
const sort = e.target.value;
setSort(sort);
};
const handleClearSort = () => {
setSort('');
};
React.useEffect(() => {
if (sort) {
const sortedImages = filteredImages.sort(
byValue((i) => i.albumId, byNumber({ desc: sort === 'desc' }))
);
setFilteredImages(sortedImages);
} else {
setFilteredImages(images);
}
setPage(1);
/* eslint-disable-next-line */
}, [sort]);
React.useEffect(() => {
console.log('NEW FILTERED IMAGES', filteredImages);
}, [filteredImages]);
<>
{!imagesLoading &&
(filteredImages.length ? (
<Grid container item spacing={5} xs={12}>
{filteredImages
.slice(itemsOnPage * (page - 1), page * itemsOnPage)
.map((image: Image) => (
<Grid item xs={4} key={image.id}>
<Card>
<CardHeader title={image.title.slice(0, 20)} />
<CardMedia
component="img"
height="100%"
image={image.thumbnailUrl}
alt={image.title}
/>
<CardActions>
<Button
size="small"
className={classNames(classes.btn, classes.deleteBtn)}
>
<DeleteIcon />
</Button>
<Button
size="small"
className={classNames(classes.btn, classes.previewBtn)}
>
<PreviewIcon />
</Button>
</CardActions>
</Card>
</Grid>
))}
</Grid>
) : (
<Grid item>
<Typography variant="body1">No images were found</Typography>
</Grid>
))}
</>
Furthermore, the useEffect, that is listening for filteredImages to change is not working. I am not getting the console.log after filteredImages change it's value.
UPD: Default sorting by Array.sort is not working either
CodePudding user response:
you can use orderBy lodash for sorting array, you can also check this answer : answer
In your case, you can write useEffect method Like this
import {orderBy} from 'lodash'
React.useEffect(() => {
if (sort) {
setFilteredImages( orderBy(filteredImages, ['albumId'], ['desc']) );
} else {
setFilteredImages(images);
}
setPage(1);
/* eslint-disable-next-line */
}, [sort]);