Search code examples
javascriptreactjsevent-handlingreact-hookssetstate

React - SetState handler Method


I have a component with the following situation:

These are two methods when i select two teams (Home, Away) in two select components

  const selectHomeTeamStat = evt => {
    const { value } = evt.target;
    setSelectedHomeOption(value);
    getStats(leagueId, value, 'home');
  };

  const selectAwayTeamStat = evt => {
    const { value } = evt.target;
    setSelectedAwayOption(value);
    getStats(leagueId, value, 'away');
  };

As you can see i am able to pass this string parameter 'Home' and 'Away' to the getStats request in order to differentiate and create then two different states

After that i have realized that instead of the strings 'Home' and 'Away' i actually need the state name of the teams to pass as parameter to the getStats request

So this changed to

  const [selectedHomeName, setSelectedHomeName] = useState("");
  const [selectedAwayName, setSelectedAwayName] = useState("");

  const selectHomeTeamStat = evt => {
    const { value } = evt.target;
    const item = items.find(item => item.team_id == value);
    setSelectedHomeOption(value);
    setSelectedHomeName(item.name);
    console.log('Home Team Name:', selectedHomeName);
    getStats(leagueId, value, selectedHomeName);
  };

  const selectAwayTeamStat = evt => {
    const { value } = evt.target;
    const item = items.find(item => item.team_id == value);
    setSelectedAwayOption(value);
    setSelectedAwayName(item.name);
    console.log('Away Team name:', selectedAwayName);
    getStats(leagueId, value, selectedAwayName);
  };

item.name returns correctly the name of the team selected so then i expect to see selectedHomeName and selectedAwayName states too but in my console.log i don't see the it

console.log('Home Team Name:', selectedHomeName); => Team Name:
console.log('Away Team Name:', selectedAwayName); => Away Name:

So the question is, what am i doing wrong? how can i pass these states to getStats inside the event handler in order to differentiate?


Solution

  • setState is asynchronous. You are logging the state in the current render phase, the updated value will be available only on the next render.

    To fix it, pass the current value item.name or use useEffect

    const selectHomeTeamStat = (evt) => {
        const { value } = evt.target;
        setSelectedHomeOption(value);
    }
    
    useEffect(() => {
      const item = items.find((item) => item.team_id == selectedHomeOption);
      getStats(leagueId, selectedHomeOption, item.name);
    }, [leagueId, items, selectedHomeOption]);