[英]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.