简体   繁体   中英

Why does my Card List Component Re-renders on every change

I do understand useEffect, perhaps not entirely, but due to some warnings, I re-structured some of my functions with useCallBack and that seemed to resolve the warning issue. The thing is I don't understand useCallBack fully, and due to tight schedule I'm unable to read the documentation and understand it properly. So I'm stuck re-rendering the same list again with every change

Here is my code:

    const getTeamById = useCallback(async (teamId) => {
    await ligaApi.get(`/teams/${teamId}/players`).then((res) => {
        const response = res.data;
        const getPlayerDataRequests = response?.map((x) => x.playerId);

        Promise.all(getPlayerDataRequests).then((res) => {
            for (let i = 0; i < res.length; i++) {
                const playerData = res[i];
                getPlayerData(playerData);
            }
        });
    });
}, []);

const getPlayersTeams = useCallback(
    async (playerId) => {
        await ligaApi.get(`/players/${playerId}/teams`).then((res) => {
    

            setTeamID(res.data[0].teamId);
            getTeamById(teamID);
        });
    },
    [getTeamById, teamID]
);
useEffect(() => {
    getPlayersTeams(playerId);
}, [getPlayersTeams, playerId]);

const getPlayerData = async (playerId) => {
    await ligaApi.get(`/players/${playerId}`).then((res) => {
        const response = res.data;
        setIsLoading(true);
        setPlayers((prevState) => [...prevState, response]);
    });
};

I noticed an error in your getPlayersTeams function, I fixed that in the code below:

  const getPlayersTeams = useCallback(
    async (playerId) => {
        await ligaApi.get(`/players/${playerId}/teams`).then((res) => {

    const dataTeamId = res.data[0].teamId

            setTeamID(dataTeamId);
            getTeamById(dataTeamId);
        });
    },
    [getTeamById, teamID]
);

You can't access the state teamId just after setting it because it is asyncronous, in your case you were passing the previous value of teamId to your dataTeamId function

The main issues are in your getPlayersTeams and useEffect hook.

const getPlayersTeams = useCallback(
  async (playerId) => {
    await ligaApi.get(`/players/${playerId}/teams`).then((res) => {
      setTeamID(res.data[0].teamId); 
      getTeamById(teamID); // here, teamID is not yet set.
    });
  },
  [getTeamById, teamID] // here, you have teamId locally, dont take it from state
);
useEffect(() => {
  getPlayersTeams(playerId);
}, [getPlayersTeams, playerId]); // here, function updates state variable and also depends on this state variable, circular.

useEffect will be triggered when any of its dependencies changes. So it triggers when getPlayersTeams is updated. And it is updated due to it has teamID in its deps array and itself it sets team id with setTeamID .

Issue about getPlayersTeams is described in another answer here but it does not fix the issue. Just because you had to remove teamID from its [depsArray] . Because it is not used inside of it anymore. Circular updates will be gone.

const getPlayersTeams = useCallback(
  async (playerId) => {
    const res = await ligaApi.get(`/players/${playerId}/teams`);
    const teamId = res.data[0].teamId;
    setTeamID(teamId);
    await getTeamById(teamId); // also await
  },
  [getTeamById]
);

Also, recommendation, separate API calls from UI updates, do not execute API calls and setting state in 1 method. And do keep an eye on promises handling, there is a few places in your code where they are not awaited. Even if it is not causing errors and bugs now - one day they will.

Ok, after discussions in comments - next issue was found - players array was not re-seted and was accumulated over and over.

useEffect(() => {
  setPlayers([]); // reset to empty array when playerId changed
  getPlayersTeams(playerId);
}, [getPlayersTeams, playerId]);

Next recommendation - dont mix async with .then() .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM