Home > Software design >  Problems sorting array with select and button in React
Problems sorting array with select and button in React

Time:12-23

I'm trying to sort an array of objects from a fetch. I have problems getting my sorting to work. I have both tried with a select and a button, but nothing works. Can anyone identify what I'm missing?

The fetch is done in the App.js and the map and sort in this component, FYI.

import React, { useState, useEffect } from "react";
import { Link } from "react-router-dom";

const FirstPage = ({ movies }) => {
  const [movieList, setMovieList] = useState(movies);

  const sortByTitle = () => {
    const sorted = [...movieList].sort((a, b) => {
      return a.title.localeCompare(b.title);
    });
    setMovieList(sorted);
  };

  // const [movie, setMovie] = useState([]);
  // const [sortMovies, setSortMovies] = useState("alphabetically");

  // useEffect(() => {
  //   const sortedMovies = (type) => {
  //     const types = {
  //       vote_average: "vote_average",
  //       release_date: "release_date",
  //       origina_title: "original_title",
  //     };
  //     const sortProperty = types[type];
  //     const sorted = [...movies].sort(
  //       (a, b) => b[sortProperty] - a[sortProperty]
  //     );
  //     console.log(sorted);
  //     setMovie(sorted);
  //   };

  //   sortedMovies(sortMovies);
  // }, [sortMovies]);

  // const sortTitle = () => {
  //   movies.sort((a, b) => a.title.localeCompare(b.title));
  // };

  return (
    <section>
      <select onChange={(e) => e.target.value}>
        <option value="vote_average">imdb rating</option>
        <option value="release_date">release date</option>
        <option value="original_title">alpabetically</option>
      </select>
      
     <button onClick={sortByTitle}>Sort by Title</button>

      {movies
        // .sort((a, b) => a.title.localeCompare(b.title))
        .map((movie) => (
          <Link key={movie.id} to={`/moviepage/${movie.id}`}>
            <h1>{movie.original_title}</h1>
            <img
              src={`https://image.tmdb.org/t/p/w300/${movie.poster_path}`}
              alt={movie.title}
            />
          </Link>
        ))}
    </section>
  );
};

export default FirstPage;

CodePudding user response:

You are mapping the movies variable, but the sorted array is stored on the movieList state

This should work

...
{movieList.map((movie) => (
...

CodePudding user response:

I tried as your idea. But no problem in my app. This made me clearly. Then, I suggest two points.

  1. Once confirm your movieList obj at the first of sortByTitle function.
  2. Another confirm top-down flow data 'movies' : type.
  3. From there, 'sorted' is a array, 'movieList' seems like a object. Just this is important. I tell you this.

Carefully, be attention.

CodePudding user response:

  const sortByTitle = () => {
    const sorted = [
      ...movieList.sort((a, b) => {
        return a.title.localeCompare(b.title);
      })
    ];
    setMovieList(sorted);
  };

That is the required code. Compare above code with your code and you'll find that you are not retuning a new array.

sort method sorts the array in place READ HERE but it doesn't return a new array(i.e., returns reference of old array). And react needs a new array in order to detect any change in the state and you can do it by providing it a new array like I did in above code.

For proof: Check this codesandbox

Thanks.

  • Related