Reputation: 100
I was using classes. I changed it to functional components. But in handleLike method. I cant seem to understand how to use setState. Anyhelp with how to do it? In my current useState im getting array of objects. When I click on like button it displays an error that movies.map is not a function. Thankyou
movies.jsx
import React, { Component, useState } from "react";
import { getMovies } from "../services/fakeMovieService";
import Like from "./like";
function Movies() {
const initialMovies = getMovies();
const [movies, setMovies] = useState(initialMovies);
const handleDelete = (movie) => {
setMovies((movies) => movies.filter((m) => m._id !== movie._id));
};
const handleLike = (movie) => {
const movies = [...movies]
const index = movies.indexOf(movie)
movies[index] = { ...movie[index]}
movies[index].liked = !movies[index].liked
setMovies({ movies })
};
const { length: count } = movies;
if (count === 0) return <p>There are no movies in database</p>;
return (
<React.Fragment>
<p> Showing {count} movies in the database</p>
<table className="table">
<thead>
<tr>
<th>Title</th>
<th>Genre</th>
<th>Stock</th>
<th>Rate</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
{movies.map((movie) => (
<tr key={movie._id}>
<td>{movie.title}</td>
<td>{movie.genre.name}</td>
<td>{movie.numberInStock}</td>
<td>{movie.dailyRentalRate}</td>
<td>
<Like liked={movie.liked} onClick={()=> handleLike(movie)} />
</td>
<td>
<button
onClick={() => handleDelete(movie)}
className="btn btn-danger btn-sm"
>
Delete
</button>
</td>
</tr>
))}
</tbody>
</table>
</React.Fragment>
);
}
Like.jsx
class Like extends React.Component {
render() {
let classes = "fa fa-heart";
if (!this.props.liked) classes+= "-o"
return (
<i
className={classes}
aria-hidden="true"
onClick={this.props.onClick}
style={{cursor:"pointer"}}
></i>
);
}
}
JSON FILE
const movies = [
{
_id: "5b21ca3eeb7f6fbccd471815",
title: "Terminator",
genre: { _id: "5b21ca3eeb7f6fbccd471818", name: "Action" },
numberInStock: 6,
dailyRentalRate: 2.5,
publishDate: "2018-01-03T19:04:28.809Z",
liked: true,
},
{
_id: "5b21ca3eeb7f6fbccd471816",
title: "Die Hard",
genre: { _id: "5b21ca3eeb7f6fbccd471818", name: "Action" },
numberInStock: 5,
dailyRentalRate: 2.5
},
{
_id: "5b21ca3eeb7f6fbccd471817",
title: "Get Out",
genre: { _id: "5b21ca3eeb7f6fbccd471820", name: "Thriller" },
numberInStock: 8,
dailyRentalRate: 3.5
},
{
_id: "5b21ca3eeb7f6fbccd471819",
title: "Trip to Italy",
genre: { _id: "5b21ca3eeb7f6fbccd471814", name: "Comedy" },
numberInStock: 7,
dailyRentalRate: 3.5
},
{
_id: "5b21ca3eeb7f6fbccd47181a",
title: "Airplane",
genre: { _id: "5b21ca3eeb7f6fbccd471814", name: "Comedy" },
numberInStock: 7,
dailyRentalRate: 3.5
},
{
_id: "5b21ca3eeb7f6fbccd47181b",
title: "Wedding Crashers",
genre: { _id: "5b21ca3eeb7f6fbccd471814", name: "Comedy" },
numberInStock: 7,
dailyRentalRate: 3.5
},
{
_id: "5b21ca3eeb7f6fbccd47181e",
title: "Gone Girl",
genre: { _id: "5b21ca3eeb7f6fbccd471820", name: "Thriller" },
numberInStock: 7,
dailyRentalRate: 4.5
},
{
_id: "5b21ca3eeb7f6fbccd47181f",
title: "The Sixth Sense",
genre: { _id: "5b21ca3eeb7f6fbccd471820", name: "Thriller" },
numberInStock: 4,
dailyRentalRate: 3.5
},
{
_id: "5b21ca3eeb7f6fbccd471821",
title: "The Avengers",
genre: { _id: "5b21ca3eeb7f6fbccd471818", name: "Action" },
numberInStock: 7,
dailyRentalRate: 3.5
}
];
export function getMovies() {
return movies;
}
Upvotes: 2
Views: 245
Reputation: 8412
You have a few redundant object/array assignment in your code
So, update your handleLike
like so:
const handleLike = (movie) => {
const _movies = [...movies];
const index = movies.indexOf(movie);
_movies[index].liked = !movies[index].liked;
setMovies(_movies);
};
Working Example:
Upvotes: 2