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

React点击图片切换类名失效:数组元素无法移除的修复方法

问题分析与修复方案

核心问题

你的代码存在两个关键错误,导致无法正常移除数组中的索引:

  1. 直接修改React状态数组:let returnArray = prevState 是引用赋值,修改returnArray等同于直接修改原状态,违反了React状态不可变的原则,会导致状态更新异常。
  2. splice返回值误用:splice方法执行后返回的是被删除元素组成的数组,而非修改后的原数组。删除操作时返回的是仅包含被删索引的数组,而非剩余元素的数组,直接导致后续状态判断失效。
  3. Strict Mode放大问题:Strict Mode下React会双重调用setState的更新函数,直接修改原状态的行为会被放大,引发更明显的异常;关闭Strict Mode后,状态更新逻辑的错误依然存在,导致当前点击项无法正确移除。

修复后的代码方案

方案一:使用filter生成新数组(简洁推荐)

function toggleFavoriteChanel(index) {
  setFavorite(prevState => {
    if (prevState.includes(index)) {
      // 过滤掉当前索引,返回全新数组
      return prevState.filter(item => item !== index);
    } else {
      // 新增索引,扩展原数组生成新数组
      return [...prevState, index];
    }
  });
}

方案二:复制原数组后修改(直观易理解)

function toggleFavoriteChanel(index) {
  setFavorite(prevState => {
    // 先复制原数组,避免修改原状态
    const newFavorite = [...prevState];
    const idx = newFavorite.indexOf(index);
    if (idx !== -1) {
      // 删除对应索引
      newFavorite.splice(idx, 1);
    } else {
      // 添加新索引
      newFavorite.push(index);
    }
    // 返回修改后的新数组
    return newFavorite;
  });
}

进阶优化建议

用数组索引作为key和存储标识存在隐患:如果visibleData数组发生增删、排序变化,索引会随之改变,导致组件复用异常或收藏状态错位。建议改用每个频道的唯一ID(比如chanel.id)替代索引:

// 修改收藏函数,存储频道ID
function toggleFavoriteChanel(chanelId) {
  setFavorite(prevState => {
    if (prevState.includes(chanelId)) {
      return prevState.filter(id => id !== chanelId);
    } else {
      return [...prevState, chanelId];
    }
  });
}

// 渲染部分调整
{Array.isArray(props.visibleData) ? props.visibleData.map((chanel, index) => {
  return (
    <div className="chanel__item" key={chanel.id}>
      <img 
        src={star} 
        alt="star" 
        onClick={() => props.toggleFavoriteChanel(chanel.id)} 
        id={chanel.id} 
        className={`star ${props.favorite.includes(chanel.id) ? 'active' : ''}`} 
      />
      <NavLink
        onClick={() => props.updateData(index)}
        end
        style={{ textDecoration: 'none' }}
        to='/ChanelPage'>
        <img src={chanel.image} alt="" className="chanel__img" />
        <div className="chanel__title">
          <div className="chanel__item-number">{index + 1}. &nbsp;</div>
          {chanel.name_ru}
        </div>
      </NavLink>
    </div> 
  ) 
}) : null}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 02:55:31