Skip to content
Advertisement

How to reuse a function for multiple select options that only use a single event handler in React

I’m building a small player simulator. You select a team and that team’s players become available. You select a player and that player’s stats become available.

I’m trying to reuse a single onChange handler for each of the select elements.

In my initial code I’m having to use a seperate player stats function for each player on the team. (homePlayer1Stats and homePlayer2Stats in the example below) Which would give me 11 stats functions for both home and away team. Can you tell me how to turn homePlayer1 homePlayer2 etc. into homePlayer(i) so I can use a single stats function?

I’ve included the App, and the team and player select components here fore completeness.

const intialValues = {
  home: 'Choose team',
  away: 'Choose team',
  homePlayer1: 'Choose Opener',
  homePlayer2: 'Choose Opener',
  awayPlayer1: 'Choose Opener'
};

function App() {
  const [values, setValues] = useState(intialValues);
    
  const handleInputChange = (e) => {
      const { name, value } = e.target;
        setValues({
          ...values,
          [name]: value,
      });
  };
  
  function homePlayerArray() {
    const filteredArray = statsFile.filter(element => {
      return element.Country === values.home
    })
    const sortedArray = filteredArray.sort((a,b) => (a.Player > b.Player) ? 1 : ((b.Player > a.Player) ? -1 : 0));
    return sortedArray;
  }

  function homePlayer1Stats() {
    const filter = homePlayerArray().filter(element => {
      return element.Player === values.homePlayer1
    })
    return filter
  }
  function homePlayer2Stats() {
    const filter = homePlayerArray().filter(element => {
      return element.Player === values.homePlayer2
    })
    return filter
  }

return (
      <>
        <h1>Simulator</h1>
        <ErrorBoundary>
          <Rules />
        </ErrorBoundary>
        <ErrorBoundary>
          <Teams
            handleInputChange={handleInputChange}
            home={values.home}
            away={values.away}
          />
        </ErrorBoundary>
        <ErrorBoundary>
          <Players 
            handleInputChange={handleInputChange}
            homePlayer1={values.homePlayer1}
            homePlayer2={values.homePlayer2}
            awayPlayer1={values.awayPlayer1}
            homePlayerArray={homePlayerArray()}
            awayPlayerArray={awayPlayerArray()}
            homePlayer1Stats={homePlayer1Stats()}
            homePlayer2Stats={homePlayer2Stats()}
          />
        </ErrorBoundary>

Part of the team select component

<h3>Home Team</h3>
  <select 
    onChange={props.handleInputChange}
    value={props.home}
    name='home'
   >
  <option value={props.home}>
     {props.home}
  </option>
                        
   {countryArray().map((element) => 
   <option key={element} value={element}>
      {element}
   </option>)}
 </select>

part of the player select component

<td>
  <select 
    onChange={props.handleInputChange}
    value={props.homePlayer1}
    name='homePlayer1'
  >
  <option value={props.homePlayer1>        
     {props.homePlayer1}
  </option>
                                    
  {props.homePlayerArray.map((element) => 
   <option 
     key={element.Player} 
     value={element.Player}
   >
   {element.Player}
   </option>)}
 </select>
</td>
 {props.homePlayer1Stats.map((element) => 
   <td 
     key={element.BatAverage} 
     value={element.BatAverage}
   >
    {element.BatAverage}
  </td>)}

Advertisement

Answer

Pass, as argument to the function, the team you want to use as filter:

function homePlayer2Stats(homePlayer) {
  const filter = homePlayerArray().filter(element => {
    return element.Player === homePlayer;
  })
  return filter;
}

Now you can reuse the function.

User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement