'How to push new value in array useState in react
I want when I click on a card of the movie name, this movie name is pushed in useSate. The problem is when I click on the same card, data is saved in the useState as an array. But when I click on a different card previous value of the useState is deleted.
Here is my code. movie is a single object.
const MovieCard = ({ movie }) => {
const [firstCat, setFirstCat] = React.useState([]);
const movieList = (movie) => {
setFirstCat([...firstCat, movie]);
}
console.log(firstCat);
return (
<div className='mt-3 cursor-pointer' onClick={() => movieList(movie)}>
<div className="max-w-sm bg-white rounded-lg border border-gray-200 shadow-md">
<img className="rounded-t-lg" src="/docs/images/blog/image-1.jpg" alt="" />
<div className="p-5">
<h5 className="mb-2 text-xl font-bold tracking-tight text-gray-900">{movie.Title}</h5>
</div>
</div>
</div>
);
};
export default MovieCard;
Solution 1:[1]
Your problem is you scoped your states only in MovieCard which means each MovieCard will have different states.
You need to add states on the upper/parent component of MovieCard. Let's assume you have MovieList contains all MovieCard
const MovieList = () => {
const [firstCat, setFirstCat] = React.useState([]);
console.log(firstCat);
return <div>
<MovieCard movie={movie} setFirstCat={setFirstCat}/>
<div/>
}
And modify your MovieCard like below
const MovieCard = ({ movie, setFirstCat }) => {
const movieList = (movie) => {
setFirstCat([...firstCat, movie]);
}
return (
<div className='mt-3 cursor-pointer' onClick={() => movieList(movie)}>
<div className="max-w-sm bg-white rounded-lg border border-gray-200 shadow-md">
<img className="rounded-t-lg" src="/docs/images/blog/image-1.jpg" alt="" />
<div className="p-5">
<h5 className="mb-2 text-xl font-bold tracking-tight text-gray-900">{movie.Title}</h5>
</div>
</div>
</div>
);
};
export default MovieCard;
This technique is called state lifting
Solution 2:[2]
Looks like each MovieCard component has its own firstCat state. When you click another movie card you are updating that card's state.
You likely need to lift state up and store the firstCat state in the common parent component so all MovieCard components can reference the same single state.
Example:
const Movies = () => {
const [movies, setMovies] = React.useState([.......]);
const [firstCat, setFirstCat] = React.useState([]);
const addMovie = (movie) => {
setFirstCat(firstCat => [...firstCat, movie]);
}
return movies.map(movie => (
<MovieCard
key={movie.id}
movie={movie}
addMovie={() => addMovie(movie)}
/>
));
}
...
const MovieCard = ({ movie, addMovie }) => {
return (
<div className='....' onClick={addMovie}>
<div className="....">
<img
className="...."
src="...."
alt=""
/>
<div className="p-5">
<h5 className="....">
{movie.Title}
</h5>
</div>
</div>
</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 | Nick Vu |
| Solution 2 | Drew Reese |

