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

React项目中收藏按钮条件渲染仅对数组首个元素生效的问题

问题描述

我有一个基于themealdb.com数据的React项目,使用Global Context获取餐食数据,通过map函数渲染所有餐食。我设置了favorites数组,希望根据餐食是否已加入收藏来渲染对应的点赞按钮。当前代码无报错,但遍历favorites数组的for循环仅对首个元素生效,无法正确判断其他餐食是否在收藏中。我尝试通过for循环遍历favorites数组,匹配idMeal后渲染不同图标,但未达到预期效果。

错误代码

按钮判断函数

function decideLikeButton(favorites,idMeal){
    if(favorites.length<1){
      return(
        <FcLike />
      )     
    }
    else if(favorites.length>0){
      for (let i=0; i<favorites.length; i++){
        if(favorites[i].idMeal === idMeal){
          return(
            <FcDislike/>
          )
        }
        else{
          return(
            <FcLike/>
          )
        }
      }
    }
  }

组件渲染部分

return <section className="section-center">
{meals.map((singleMeal) => {
  const { idMeal, strMeal: title, strMealThumb: image } = singleMeal
  return <article key={idMeal} className={darkMode? "single-meal-dark": "single-meal"}>
    <img src={image} className='img' onClick={() => selectMeal(idMeal)} />
    <footer>
      <h5>{title}</h5>
      <button className="like-btn" onClick={() => { addToFavorites(idMeal) }}> 
        {
          decideLikeButton(favorites, idMeal)
        }
       </button>
    </footer>
  </article>
})}

问题原因

decideLikeButton函数里的for循环逻辑错误:遍历到第一个元素时,不管是否匹配都会直接return,导致后续收藏项根本没机会被检查。比如第一个收藏项不是当前餐食,函数直接返回<FcLike/>,不会继续验证后面的元素。

修复方案

改用数组的some方法判断当前餐食是否在收藏数组中,逻辑更简洁可靠:

优化后的按钮判断函数

function decideLikeButton(favorites, idMeal) {
  // some方法会遍历数组,只要找到匹配项就返回true
  const isInFavorites = favorites.some(item => item.idMeal === idMeal);
  return isInFavorites ? <FcDislike/> : <FcLike/>;
}

更简洁的写法:直接在渲染时判断

可以省去单独的函数,直接在按钮内完成判断:

<button className="like-btn" onClick={() => addToFavorites(idMeal)}> 
  {favorites.some(item => item.idMeal === idMeal) ? <FcDislike/> : <FcLike/>}
</button>

内容的提问来源于stack exchange,提问作者Ferhat Arda Ersoy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 10:05:18