Home > Net >  React huge array sorting (5k items)
React huge array sorting (5k items)

Time:10-27

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

  • Related