0

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

1 Answer 1

1

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

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much! Your suggestion worked!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.