我有一个轮播组件,希望在每张卡片上都有一个“喜欢”按钮。我怎样才能在功能组件中做到这一点?当我在“喜欢”按钮上使用“useState”时,反应会出现在每个孩子(每张卡片)上。我该如何处理这个问题?
我希望当我点击“喜欢”按钮时,每个人的新喜欢计数都会单独增加,并且只向特定的孩子(卡片)显示反应。
<> <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>
</>
);
};
count
是一个整数。 该值应适用于哪张卡? 您本质上是在尝试使用一个数字来计算许多事物。
这也意味着您错误地命名了组件。 它被称为“抽认卡”,但包含许多“卡片”,它包含一个“计数”的值,但预计会有很多“计数”。 总的来说,您基本上混淆了“单一”和“复数”。区分概念。 有一个保存卡片的父组件,并让每张卡片保持其状态。 例如,考虑这个卡片组件:
export const Card = ({ item }) => {
const [count, setCount] = useState(0);
const increment = () => {
setCount((prev) => (prev += 1));
};
return (
<div className="box">
<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>
);
};
此 Card
组件根据传递给它的
item
显示在“卡片”上,并在内部跟踪
count
被点击的次数。然后父组件就可以直接显示卡片了:
import React, { useState } from "react";
import Slider from "react-slick";
export const FlashCards = ({ productItems }) => {
const settings = {
dots: false,
infinite: true,
speed: 500,
slidesToShow: 4,
slidesToScroll: 1,
};
return (
<>
<Slider {...settings}>
{productItems.map((item) => {
return <Card item={item} key={item.id} />;
})}
</Slider>
</>
);
};
需要父组件上的卡片计数,例如,根据卡片的计数来过滤卡片。
在这些情况下,您可以在父组件中使用计数数组,并根据每张卡的原始索引增加其计数,并将此计数作为 prop 传递给每张卡。像这样:
import React, { useState } from "react";
export const FlashCards = ({ productItems }) => {
const settings = {
dots: false,
infinite: true,
speed: 500,
slidesToShow: 4,
slidesToScroll: 1,
};
// all cards starting with count 0
const [cardCounts, setCardCounts] = useState([...new Array(productItems.length)].map((_elem) => 0)
const onIncrement = (cardIndex) => {
// increment just the one card in our array and keep everything else the same
setCardCounts((prev) => [
...prev.slice(0, cardIndex),
prev[cardIndex] + 1,
...prev.slice(cardIndex + 1)
])
}
return (
<>
<Slider {...settings}>
{productItems.map((item, cardIndex) => {
return <Card item={item} key={item.id} onClickIncrement={() => onIncrement(cardIndex)} count={cardCounts[cardIndex]} />;
})}
</Slider>
</>
);
};
然后只需在需要时调用 Card 组件内的函数 onClickIncrement(),并根据需要显示计数,从其 props 中获取两者:
const Card = ({ card, onClickIncrement, count }) => {
// ...
}
代码变得有点麻烦,但我认为这种逻辑在很多用例中都很方便。