[英]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
主要问题在于您的getPlayersTeams
和useEffect
挂钩。
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.