I have a Carousel Component and want to have a "like" button on each card. How could I do this in the function component? When I use "useState" on the "like" button and the reaction appears on each child (each card). How I could handle this?
I would like when I click on the "like" button the new counting of likes to be increased separately for each one, and only the reaction to be shown to the particular child (card).
<> <Card name="A" likes={0} /> <Card name="B" likes={1} clicked /> </>
// FlashDeals.jsx
import React, { useState } from "react";
import Slider from "react-slick";
export const FlashCard = ({ productItems }) => {
const [count, setCount] = useState(0);
const increment = (prev) => {
setCount((prev) => (prev += 1));
};
const settings = {
dots: false,
infinite: true,
speed: 500,
slidesToShow: 4,
slidesToScroll: 1,
};
return (
<>
<Slider {...settings}>
{productItems.map((item) => {
return (
<div className="box" key={item.id}>
<div className="product">
<div className="img">
<span className="discount">{item.discount}% Off</span>
<img src={item.cover} alt="" />
<div className="product-like">
<label>{count}</label>
<br />
<i className="fa-regular fa-heart" onClick={increment}></i>
</div>
</div>
</div>
</div>
);
})}
</Slider>
</>
);
};
2
Answers
count
is a single integer. Which card should that value apply to? You’re essentially trying to use one number to count many things.Which also means you’ve mis-named your component. It’s called a "flashcard" but holds many "cards", it contains a value for one "count" but is expected to have many "counts". Overall you’re basically confusing "single" with "plural".
Separate the concepts. Have a parent component which holds the cards, and have each card maintain its state. For example, consider this card component:
This
Card
component displays on "card" based on theitem
passed to it, and internally tracks thecount
of how many times it has been clicked.Then the parent component can just display the cards:
I like David’s answer, it keeps your code clean and easy to work with. However, in some cases you might need the Card count on the parent component, say, for instance, to filter cards based on their count.
In these cases, you can use an array of counts in the parent component, and you’d increment the count of each card based on their original index, and pass this count to each card as prop. Like so:
And then just call the function onClickIncrement() inside the Card component when you desire, and display the count as you wish, getting both from its props:
The code becomes a bit more cumbersome, but I think this logic comes across handy in a lot of use cases.