'Toggle icon with error in reactjs. How to solve?
By clicking on the heart icon I want to change the color to red and add it to the favorite. When clicking again, it goes back to gray and remove from favorite. But when I click on an icon they all change color. How to fix to change only the icon that was clicked?
const Destaques = () => {
const { destaques, favoriteList, setFavoriteList, isFavorite, setIsFavorite, handlerIcon } = useContext(MoviesContext);
const [showStatus, setShowStatus] = useState(false);
const handleShow = () => setShowStatus(true);
const handleClose = () => setShowStatus(false);
var settings = {
infinite: false,
autoplay: true,
speed: 500,
slidesToShow: 4,
infinite: true,
slidesToScroll: 1,
initialSlide: 0,
responsive: [
{
breakpoint: 1024,
settings: {
slidesToShow: 3,
slidesToScroll: 1,
infinite: true,
}
},
{
breakpoint: 600,
settings: {
slidesToShow: 2,
slidesToScroll: 1,
initialSlide: 2
}
},
{
breakpoint: 480,
settings: {
slidesToShow: 1,
slidesToScroll: 1
}
}
]
};
const filteredHighlight = destaques.filter(movie => movie.highlight === true);
const sliders = () => {
return filteredHighlight.map((data) => {
return (
<div>
<div className='container-card' key={data.id}>
<div className='card-img'>
<img alt={data.title} src={data.poster} onClick={handleShow} />
<i onClick={handlerIcon}>
{isFavorite ?
<FaHeart className='heartIcon' style={{ color: 'red' }} /> : <FaHeart className='heartIcon' style={{ color: '#BABABA' }} />
}
</i>
</div>
<div className='box-content'>
<div className='box-title-vote'>
<h4 className='card-title'>
{data.title}
</h4>
<div className='box-vote-like'>
<span className='card-vote-average'>4/5</span>
<i className='icon-like-destaques'>
<img src={IconLike} alt="icon like"></img>
</i>
</div>
</div>
<p className='card-overview'>
{data.overview}
</p>
</div>
</div>
<Modal show={showStatus} onHide={handleClose} backdrop="static" centered >
<Modal.Header closeButton>
</Modal.Header>
<Modal.Body >
<DefaultDetail id={data.id} poster={data.poster} overview={data.overview} title={data.title} />
</Modal.Body>
</Modal>
</div>
);
});
}
return (
<div>
<h3 className='title-destaque'>Destaques</h3>
<Slider {...settings}>
{sliders()}
</Slider>
</div>
);
}
export default Destaques
Before clicking the icon
After clicking the icon

Code to add, remove and toggle icon favorite.
const MoviesContextProvider = props => {
const results = dataAllMovies.movies;
const [destaques, setDestaques] = useState(results);
const [allMovies, setAllMovies] = useState(results);
const [isFavorite, setIsFavorite] = useState(false);
const [favoriteList, setFavoriteList] = useState([]);
//favorite
const getMovieStorage = () => {
if (localStorage.getItem("favorites")) {
let favoriteList = JSON.parse(localStorage.getItem("favorites"));
return favoriteList
}
else {
let favoriteList = []
return favoriteList
}
}
useEffect(() => {
if (favoriteList.includes(allMovies.id)) {
setIsFavorite(!isFavorite);
const favorite = getMovieStorage();
setFavoriteList(favorite);
}
}, []);
const handlerIcon = (e) => {
setIsFavorite(!isFavorite);
if (isFavorite) {
var index = favoriteList.indexOf(allMovies.id);
favoriteList.splice(index, 1);
setFavoriteList(favoriteList);
deleteMovie(allMovies.id);
}
else {
setFavoriteList(favoriteList.concat([allMovies.id]));
addMovie(allMovies.id);
}
}
const deleteMovie = (id) => {
const Favorite = getMovieStorage();
var index = Favorite.indexOf(id)
Favorite.splice(index, 1);
localStorage.setItem("FavoritList", JSON.stringify(Favorite));
}
const addMovie = (id) => {
const Favorite = getMovieStorage();
Favorite.push(id)
localStorage.setItem("FavoritList", JSON.stringify(Favorite))
}
return (
<MoviesContext.Provider value={{ allMovies, destaques, filterMovies, filteredMovies, isFavorite, setIsFavorite, addFavoriteMovie, removeFavoriteMovie, handleFavClick, handlerIcon, favoriteList, getMovieStorage }}>
{props.children}
</MoviesContext.Provider>
);
}
export default MoviesContextProvider
PLEASE HELP ME. I NEED TO SOLVE THIS PROBLEM.
Solution 1:[1]
You must have an array of movies ids and check it with each movie id, now you check isFavorite, is not true
change isFavorite condition to => favoriteList.includes(data.id)
and fill favoriteList with movies ids in your context
<div className='card-img'>
<img alt={data.title} src={data.poster} onClick={handleShow} />
<i onClick={handlerIcon}>
{favoriteList.includes(data.id) ?
<FaHeart className='heartIcon' style={{ color: 'red' }} /> : <FaHeart className='heartIcon' style={{ color: '#BABABA' }} />
}
</i>
</div>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Erfan HosseinPoor |
