Mitchell
Mitchell

Reputation: 23

Set state based on value of array item in previous state

Hello I am new to programming and I am trying to make a function in React that adds a team to an array of selected teams but only if there are less than 2 teams selected and if the team is available (not already chosen). It is working to limit the array to only 2 values but the array will accept the same team twice and I am not sure why. For example if the user clicks ATL twice then that team will be in the array twice. What did I do wrong here and what should I change in order to fix it? Sorry if the question is too simple for this forum, I am new.

Here is the code where I am changing the state and checking if gameState.selected_teams[0] != team:

function App() {

  const [gameState, setGameState] = useState({
    cards: Cards,
    selected_teams: []
  });

  function setTeam(team){
    if (gameState.selected_teams.length < 2 && gameState.selected_teams[0] != team) {
      setGameState((prevState) => ({
        cards: prevState.cards,
        selected_teams: [
          ...prevState.selected_teams, {
            team
          }
        ]
      }))
    } 
  }

And for the component that calls the setTeam function:

function TeamSelect({cards, setTeam}) {
    var teams = Object.keys(cards);
    return (
        <div className='flex-container'>
            <div className='team-container'>
                {
                    teams.map(team => (
                        <div 
                        onClick={() => setTeam(team)}
                        className='team-label' key={team}>
                            {team}
                        </div>
                    ))
                }
            </div>
        </div>
    )
}

Upvotes: 1

Views: 58

Answers (1)

Nick Parsons
Nick Parsons

Reputation: 50759

You're adding an object {team: team} to your selected teams array each time you perform your click here:

selected_teams: [
  ...prevState.selected_teams, {
    team
  }
]

but your team key that you pass into your setTeam function is a string, so your comparison fails as you're trying to compare a string with an object. You can change your comparison to extract the team property from your object:

gameState.selected_teams[0]?.team != team

The ? ensures that a value exists at index 0 in your array before using .team on it (otherwise you would get an error if it's undefined).

You can adapt this code to handle more than one object by using .every() to check that all objects in selected_team's aren't equal to the one you're adding:

if(gameState.selected_teams.length < 2 && gameState.selected_teams.every(obj => obj.team != team)

If you don't need to pass an object {team: team} (as an object with one property doesn't add much value), then you can simply push your team string into your selected teams, and use .includes() to check if the team you're adding already exists in the array:

selected_teams: [
  ...prevState.selected_teams, team
]

you can then update your condition to use .includes():

if(gameState.selected_teams.length < 2 && !gameState.selected_teams.includes(team))

Upvotes: 3

Related Questions