Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

show dynamic select items mapping over array of objects

I have an array that looks like this:

const teamsAndPlayers = [
    {
        team: 'Liverpool',
        players: ['Salah', 'Henderson']
    },
    {
        team: 'Man Utd',
        players: ['Rashford', 'De Gea']
    },
    {
        team: 'Chelsea',
        players: ['Hazard', 'Willian']
    }
];

I have 2 select boxes, the second of which is dynamic based on what the user selects. The issue I am having is that I am not sure the best way to find the related array based on the user choice. I know I could use find and other methods, but is there anyway I can do it all in the map function in the return statement?

My code looks like the following:

const Menu = () => {

   const [selectedTeam, setSelectedTeam] = useState(null);

   return (
      <div>
        <select 
           onChange={e => setSelectedTeam(e.target.value)} 
           id="team" 
           name="team"
        >
         {teamsAndPlayers(item => (
            <option key={item.team} value={item.team}>
               {item.team}
            </option>
        ))}

        <select id="players" name="players">
         {teamsAndPlayers(item => (
            // how can I get the related players in here 
            // based on first select choice?
        ))}

      </div>
   )
}
like image 256
peter flanagan Avatar asked Jun 04 '26 19:06

peter flanagan


2 Answers

I would use object instead of array to define the input for the selects (if you really want to avoid using find). So the teamsAndPlayers would look like this:

const teamsAndPlayers = {
  liverpool: {
    name: 'Liverpool',
    players: ['Salah', 'Henderson']
  },
  manUtd: {
    name: 'Man Utd',
    players: ['Rashford', 'De Gea']
  },
  chelsea: {
    name: 'Chelsea',
    players: ['Hazard', 'Willian']
  }
};

Then the options inside the fisrt select would look like this:

{Object.keys(teamsAndPlayers).map(key => (
  <option key={key} value={key}>
    {teamsAndPlayers[key].name}
  </option>
))}

Then the options inside the second select would look like this:

{teamsAndPlayers[selectedTeam].players.map(player => (
  <option key={player} value={player}>
    {player}
  </option>
))}
like image 67
knightburton Avatar answered Jun 06 '26 07:06

knightburton


Simply combine find and map (if you don't want to change your data Array structure):

const playersByTeam = teamsAndPlayers.find(({ team }) => team === selectedTeam).players

<select id="players" name="players">
  { playersByTeam.map(player => <option key={player>{ player }</option>) }
</select>
like image 20
Jordan Enev Avatar answered Jun 06 '26 08:06

Jordan Enev