简体   繁体   English

为什么我的卡片列表组件在每次更改时都会重新渲染

[英]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.我确实了解 useEffect,也许并不完全了解,但由于一些警告,我使用 useCallBack 重新构建了一些函数,这似乎解决了警告问题。 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.问题是我不完全理解 useCallBack,而且由于时间紧迫,我无法阅读文档并正确理解它。 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:我注意到您的 getPlayersTeams function 中有一个错误,我在下面的代码中修复了它:

  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您无法在设置后访问 state teamId,因为它是异步的,在您的情况下,您将 teamId 的先前值传递给您的 dataTeamId function

The main issues are in your getPlayersTeams and useEffect hook.主要问题在于您的getPlayersTeamsuseEffect挂钩。

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. useEffect将在其任何依赖项发生更改时触发。 So it triggers when getPlayersTeams is updated.因此它会在getPlayersTeams更新时触发。 And it is updated due to it has teamID in its deps array and itself it sets team id with setTeamID .并且由于它的 deps 数组中有teamID并且它本身使用setTeamID设置团队 id 而被更新。

Issue about getPlayersTeams is described in another answer here but it does not fix the issue.关于getPlayersTeams的问题在此处的另一个答案中进行了描述,但它不能解决问题。 Just because you had to remove teamID from its [depsArray] .仅仅因为您必须从其[depsArray]中删除teamID 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.此外,建议将 API 调用与 UI 更新分开,不要执行 API 调用并在 1 方法中设置 state。 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.好的,经过评论讨论 - 找到下一个问题 - players数组没有重新设置,并且一遍又一遍地积累。

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

Next recommendation - dont mix async with .then() .下一个建议 - 不要将async.then()混合使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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