如何控制多组件状态:实现点击图片为对应组件添加类
解决方案
要实现多个组件同时添加类名,你需要把单个值的状态改成能存储多个选中项的结构,比如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}. </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,提问作者Даниил Владимиров
相关产品推荐
相关产品推荐

