繁体   English   中英

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

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

我确实了解 useEffect,也许并不完全了解,但由于一些警告,我使用 useCallBack 重新构建了一些函数,这似乎解决了警告问题。 问题是我不完全理解 useCallBack,而且由于时间紧迫,我无法阅读文档并正确理解它。 因此,每次更改时,我都会再次重新渲染相同的列表

这是我的代码:

    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]);
    });
};

我注意到您的 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]
);

您无法在设置后访问 state teamId,因为它是异步的,在您的情况下,您将 teamId 的先前值传递给您的 dataTeamId function

主要问题在于您的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将在其任何依赖项发生更改时触发。 因此它会在getPlayersTeams更新时触发。 并且由于它的 deps 数组中有teamID并且它本身使用setTeamID设置团队 id 而被更新。

关于getPlayersTeams的问题在此处的另一个答案中进行了描述,但它不能解决问题。 仅仅因为您必须从其[depsArray]中删除teamID 因为它不再在里面使用了。 循环更新将消失。

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]
);

此外,建议将 API 调用与 UI 更新分开,不要执行 API 调用并在 1 方法中设置 state。 并且要密切注意承诺的处理,在你的代码中有几个地方没有等待它们。 即使它现在不会导致错误和错误 - 有一天它们会。

好的,经过评论讨论 - 找到下一个问题 - players数组没有重新设置,并且一遍又一遍地积累。

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

下一个建议 - 不要将async.then()混合使用。

暂无
暂无

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

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