Home > Software design >  Problems with conditional rendering
Problems with conditional rendering

Time:12-21

I'm trying to mark divs that is clicked on my website. When I click, the array is updated but the mark won't show. It seems like the statement gameChoices.includes('Fortnite') is false, even though the array contains the exact value Fortnite.

Does anyone know why this happens? Eventually a new solution for the problem?

Code:

<Container onClick={() => {
  if (gameChoices.includes('Fortnite')) {
    const findIndex = gameChoices.findIndex(a => a === 'Fortnite')

    findIndex !== -1 && gameChoices.splice(findIndex , 1)
  } else if (gameChoices.includes('Fortnite') === false) {
    gameChoices.push('Fortnite')
  }
}} fluid className="d-flex fortnite gameoption position-relative">
  {gameChoices.includes('Fortnite') ? 
    <>
      <BsCheckSquare color="lightgreen" size="2rem" style={{ top: '50%', right: '50%' }} />
    </>
    : null
  }
  <h1 className="fw-bolder text-light text-center m-auto">FORTNITE</h1>
</Container>
const [gameChoices, setGameChoices] = useState([])

gameChoices data

CodePudding user response:

As I have commented:

  • Do not use inline click handler. It makes your markup difficult to read.
  • findIndex !== -1 is not required as you are already checking if it is included in array
  • Also gameChoices.includes('Fortnite') === false is redundant. Just a simple else is enough

But in addition to this, you need to set value to state.

Apart from that, you should instead look into .some and check for same cased text. You can in addition do trim if game name is coming from user input

const choiceExists = (game) => {
    return gameChoices.some(
    (name) => name.toLowerCase() === game.toLowerCase()
  )
}
const clickHandler = () => {
    const name = 'fortnite'
  if (choiceExists(name)) {
    const newGames = gameChoices.filter((game) => game.toLowerCase() !== name)
    setGameChoices(newGames)
  } else {
    setGameChoices((choices) => choices.concat(name))
  }
}

<Container onClick={clickHandler} fluid className="d-flex fortnite gameoption position-relative">
  {
    gameChoices.includes('Fortnite')
      ? <BsCheckSquare
          color="lightgreen"
          size="2rem"
          style={{ top: '50%', right: '50%' }} />
      : null
  }
  <h1 className="fw-bolder text-light text-center m-auto">FORTNITE</h1>
</Container>

CodePudding user response:

When you update a reactive state value you should use the state setter method, so setGameChoices((choices)=>[...choices, 'Fortnite'])

  • Related