skip to Main Content

I have app about hockey statistics, I dont have endpoint with this stats , I have endpoint with team and player stats. I am calling api with first team , select first 2 players save to arr and call api again with another team query, find top players from another team and save it .
Than sort topPlayers and display it.
When I open console.log() => NETWORK i can see API with specific team is called twice.
How to fix it?

const teamQuery = useMemo(() => {
    return [
      "NSH", "TBL", "PIT", "CHI", "VGK", "MIN", "ANA",
      "FLA", "PHI", "WSH", "ARI", "NYI", "SJS", "CGY",
      "BUF", "NYR", "CBJ", "NJD", "DET", "DAL",
      "TOR", "MTL", "BOS", "LAK", "COL", "WPG",
      "SEA", "CAR", "OTT", "EDM", "STL", "VAN"
    ];
  }, []);

  const fetchTeamData = async (teamQuery) => {
    try {
      const queryParam = encodeURIComponent(teamQuery);
      const res = await axios.get(`/api/NHL/findTeam?team=${queryParam}`);
      return res.data.data; 
    } catch (error) {
      console.error(error);
      return null; 
    }
  };



const fetchAllTeamsData = useCallback(async () => {
    setLoad(true);
    const topPlayers = [];

    for (const team of teamQuery) {

      setClub(team);
      const teamData = await fetchTeamData(team);

      if (teamData && teamData.players) {
        const sortedPlayers = teamData.players.sort((a, b) => b.stats.points - a.stats.points);
        const teamTopPlayers = sortedPlayers.slice(0, 2);
        topPlayers.push(...teamTopPlayers);
      }
    }

    // sort players 
    const sortedTopPlayers = topPlayers.sort((a, b) => b.stats.points - a.stats.points);
    setAllTopPlayers(sortedTopPlayers);

    const sortedTopGoals = [...topPlayers].sort((a, b) => b.stats.goals - a.stats.goals);
    setTopGoals(sortedTopGoals);

    const sortedTopAssists = [...topPlayers].sort((a, b) => b.stats.asists - a.stats.asists);
    setTopAssists(sortedTopAssists);

    const sortedMostPIM = [...topPlayers].sort((a, b) => b.stats.penalty - a.stats.penalty);
    setMostPIM(sortedMostPIM);

    setLoad(false);
  }, [teamQuery]);

  useEffect(() => {
    fetchAllTeamsData();
  }, [fetchAllTeamsData]);

2

Answers


  1. 1 – You began by declaring a teamQuery using useMemo(). This is fine as it improves performance by memorising the array and recreating it only when the dependency array changes. Here, the dependency array is empty which means the array never changes.

    2 – Then you declared fetchAllTeamsData using useCallback(). This hook returns a memoized version of the callback function that only changes if one of the dependencies has changed. In this case, teamQuery is the only dependency.

    3 – Lastly, you introduced an effect via useEffect(), calling fetchAllTeamsData whenever fetchAllTeamsData itself changes. This creates a circular effect: when fetchAllTeamsData runs, it changes its own reference, causing the effect to be re-run.

    4 – To solve this issue, you can move the teamQuery array outside of the component or simply define it as a constant inside the component, removing the need for useMemo() and useCallback(). This way, it won’t trigger unnecessary re-renders or re-calls of your function.

    Login or Signup to reply.
  2. Read this: https://react.dev/reference/react/StrictMode

    It‘s a feature, not a bug! This will be go away in Production.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search