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.
- Once confirm your movieList obj at the first of sortByTitle function.
- Another confirm top-down flow data 'movies' : type.
- 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.