Home > Net >  Conditional rendering only works for first element of the array
Conditional rendering only works for first element of the array

Time:10-05

I have a project that renders meals from "themealdb.com". Using Global Context and importing the data from Global Context. Every meal that themealdb provides rendered with "map" function. I have an array named "favorites" and if meal added to favorites already I wanted to render like button accordingly.

My goal is to render like button according if meal already in the favorites array. I am not having any error message with my code right now but I have a for loop for iteration in favorites array but it only works for first element.

I've tried to iterate with foor loop for each element in the favorites array and if id's match I wanted it to render a different icon for the each meal in the map function.

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/>
          )
        }
      }
    }
  }

And here is my return for the component

 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>
})}

CodePudding user response:

The problem is related to your for loop. You break the loop by returning in the first iteration. You need to replace this part:

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

with this code:

for (let i=0; i<favorites.length; i  ){
    if(favorites[i].idMeal === idMeal){
      return(
        <FcDislike/>
      )
    }
}

return(
    <FcLike/>
)

CodePudding user response:

Re writing decideLikeButton function

function decideLikeButton(favorites, idMeal){
 if(favorites.findIndex(fav => fav.idMeal === idMeal) !== -1) {
    return <FcDislike/>

 } else {
    <FcLike/>
 }
}

CodePudding user response:

This is because you always return on the first iteration, try this instead:

function decideLikeButton(favorites, idMeal) {
  if (favorites.some((favorite) => favorite.idMeal === idMeal)) {
    return <FcDislike />;
  }
  return <FcLike />;
}

CodePudding user response:

Id personally go for:

const getReactionIcon = (favorites, lookUpIdMeal) => {
  if (favorites.some(({ idMeal }) => idMeal === lookUpIdMeal)) return <FcDislike />


return <FcLike />;
}
  • Related