为多个项目创建类似按钮

Creating like button for multiple items

我是 React 的新手,正在尝试通过创建项目来了解更多信息。我进行了 API 调用以在页面上显示一些图像,我想为每个单击时变为红色的图像创建一个类似 button/icon 的图像。但是,当我单击一个按钮时,所有图标都会变为红色。我相信这可能与我设置状态的方式有关,但似乎无法弄清楚如何单独定位每个项目。任何见解将不胜感激。

`
 //store api data
 const [eventsData, setEventsData] = useState([]);

 //state for like button
 const [isLiked, setIsLiked] = useState(false);

useEffect(() => {
 axios({
  url: "https://app.ticketmaster.com/discovery/v2/events",
  params: {
    city: userInput,
    countryCode: "ca",
  },
  })
  .then((response) => {
    setEventsData(response.data._embedded.events);
  })
  .catch((error) => {
    console.log(error)
  });
});

//here i've tried to filter and target each item and when i 
console.log(event) it does render the clicked item, however all the icons 
change to red at the same time
  const handleLikeEvent = (id) => {
   eventsData.filter((event) => {
     if (event.id === id) {
       setIsLiked(!isLiked);
     }
    });
  };

return (
   {eventsData.map((event) => {
        return (
          <div key={event.id}>
              <img src={event.images[0].url} alt={event.name}></img>
              <FontAwesomeIcon
                 icon={faHeart}
                 className={isLiked ? "redIcon" : "regularIcon"}
                 onClick={() => handleLikeEvent(event.id)}
               />
          </div>
)

  `

 

你的问题出在你的状态上,isLiked 只是一个布尔值 true 或 false,它无法区分按钮 1 或按钮 2 等等,所以你需要一种方法来改变 css 属性 对于单个按钮,您可以通过查看 Siva 的答案找到这样的实现,您将它们的 ID 存储在一个数组中

将点赞存储为 ID 数组

const [eventsData, setEventsData] = useState([]);
const [likes, setLikes] = useState([]);

const handleLikeEvent = (id) => {
  setLikes(likes.concat(id));
};

return (
  <>
    {eventsData.map((event) => {
      return (
        <div key={event.id}>
          <img src={event.images[0].url} alt={event.name}></img>
          <FontAwesomeIcon
            icon={faHeart}
            className={likes.includes(event.id) ? "redIcon" : "regularIcon"}
            onClick={() => handleLikeEvent(event.id)}
          />
        </div>
      );
    })}
  </>
);