You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何控制多组件状态:实现点击图片为对应组件添加类

解决方案

要实现多个组件同时添加类名,你需要把单个值的状态改成能存储多个选中项的结构,比如Set(推荐,天然去重)或者对象。下面是具体修改方案:

1. 替换状态类型

把原来单个值的favorite改成Set类型,用来存储所有选中的组件索引:

const [favorite, setFavorite] = useState(new Set());

2. 修改状态更新函数

更新addFavoriteChanel,实现点击时切换当前组件的选中状态(选中则取消,未选中则添加):

function addFavoriteChanel(index) {
  setFavorite(prev => {
    const newSet = new Set(prev);
    if (newSet.has(index)) {
      newSet.delete(index); // 已选中,移除
    } else {
      newSet.add(index); // 未选中,添加
    }
    return newSet;
  });
}

用函数式更新是因为要基于上一次的状态修改,避免状态更新不及时的问题。

3. 调整类名判断逻辑

在className里检查当前索引是否在favorite集合中:

className={`star ${favorite.has(index) ? 'active' : ''}`}

修改后的完整代码

import { useState, useEffect } from 'react';

// 假设star是已导入的图片资源
const YourComponent = () => {
  const [chanelData, setChanelData] = useState([]);
  const [favorite, setFavorite] = useState(new Set());

  // 切换收藏状态
  function addFavoriteChanel(index) {
    setFavorite(prev => {
      const newSet = new Set(prev);
      newSet.has(index) ? newSet.delete(index) : newSet.add(index);
      return newSet;
    });
  }
  
  // 获取API数据
  async function getResponse() {
    try {
      let response = await fetch('https://api.json'); // 补全正确的API地址
      let content = await response.json();
      setChanelData(content.channels);
    } catch (err) {
      console.error('获取数据失败:', err);
    }
  }

  useEffect(() => {
    getResponse();
  }, []);

  // visibleData 假设是经过筛选后的chanelData
  const visibleData = chanelData; // 根据实际逻辑替换

  return (
    <div className="container">
      {Array.isArray(visibleData) ? visibleData.map((chanel, index) => {
        return (
          <div href={chanel.url} className="chanel__item" key={index}>
            <img 
              src={star} 
              alt="star" 
              onClick={() => addFavoriteChanel(index)} 
              id={index} 
              className={`star ${favorite.has(index) ? 'active' : ''}`} 
            />
            <img src={chanel.image} alt={chanel.name_ru} className="chanel__img" />
            <div className="chanel__title">
              <div className="chanel__item-number">{chanel.number}. &nbsp;</div>
              {chanel.name_ru}
            </div>
          </div> 
        );
      }) : null}
    </div>
  );
};

export default YourComponent;

可选:用对象存储状态

如果更习惯用对象,也可以这样写:

const [favorite, setFavorite] = useState({});

function addFavoriteChanel(index) {
  setFavorite(prev => ({
    ...prev,
    [index]: !prev[index] // 切换对应索引的布尔值
  }));
}

// 类名判断改成
className={`star ${favorite[index] ? 'active' : ''}`}

内容的提问来源于stack exchange,提问作者Даниил Владимиров

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 17:35:25