I am new in React, currently taking a course. While doing the exercise, the teacher cloned the same object on it and I don't understand its utility. I commented the line and all is working perfectly. I thought that the teacher made it by mistake, but he did the same thing in another exercise.
Here is the code:
handleLike = (movie) => {
const movies = [...this.state.movies];
const index = movies.indexOf(movie);
movies[index] = { ...movies[index] }; // It is about this line!
movies[index].liked = !movies[index].liked;
this.setState({ movies });
};
What is the use of this line movies[index] = { ...movies[index] };
?
CodePudding user response:
This is because you don't want to operate on the original objects from the current state as they are references. The React's state is immutable, so you always want to work on new objects when modifying their values.
movies[index] = { ...movies[index] };
creates a new object with all properties of the original one. In the next line (movies[index].liked = !movies[index].liked;
) you are modifying the liked
value of the new object. Because you've copied the object before, you don't actually mutate the original one but rather work on the new one.
CodePudding user response:
I'll focus on your question about this particular line:
movies[index] = { ...movies[index] };
1) What does this line does?
This line mutates the movies
array, and copy-paste the original content from the same index
element.
Then, the next line mutates this element directly.
2) Do we need to do this?
No.
This approach is very common on object-oriented programming languages. But while using React, an immutable approach is more simple and clean.
Here is an immutable solution for the same function:
handleLike = (movie) => {
const movies = [...this.state.movies];
const index = movies.indexOf(movie);
const updatedMovies = movies.map((movie, movieIndex) => {
if (movieIndex === index) {
return { ...movie, liked: !movie.liked };
} else {
return movie;
}
});
this.setState({ movies: updatedMovies });
};