[英]Array in React being mutated
我已經閱讀了幾個關於防止數組在 React 中發生變異的條目,但我不明白為什么我的原始數組發生了變異。 在 componentDidMount 中,我將轉到數據庫並檢索每周的輸贏記錄並將記錄保存到狀態。 (每周一個團隊打三場比賽。)
async componentDidMount() {
document.body.style.background = '#9bcaf1';
await this.getInitialStats();
this.processStats();
}
async getInitialStats(): Promise<void> {
const allRecords: TeamWeek[] = await getAllResults();
this.setState({
allRecords,
});
}
然后我調用第二個函數,該函數獲取每周每個團隊的記錄並將它們組合成一個記錄。 因此,如果一支球隊在三周內每場都輸掉了三場比賽,那么這應該合並為一個記錄,顯示該球隊輸掉了九場比賽。 我將其保存為單獨的狀態變量。 然而,原始狀態數組也在發生變異,即使我認為我是在克隆數組。 我可以推入克隆的數組,並且它可以正常工作,但是該函數的某些內容將事情搞砸了。
processStats(): void {
const allRecordsClone = [...this.state.allRecords];
const combinedRecords: TeamWeek[] = calculateOverallStats(allRecordsClone);
this.setState({
combinedRecords,
});
}
export const calculateOverallStats = (allRecords: TeamWeek[]): TeamWeek[] => {
const allRecordsClone = [...allRecords];
const combinedRecs: TeamWeek[] = [];
const teamNamesCollected: string[] = [];
// Combine wins, losses, ties, points
allRecordsClone.forEach((rec) => {
const { team_name, wins, losses, ties, total_points } = rec;
if (!teamNamesCollected.includes(team_name)) {
combinedRecs.push(rec);
teamNamesCollected.push(team_name);
} else {
const teamIndex = combinedRecs.findIndex((combRec) => combRec.team_name === team_name);
combinedRecs[teamIndex].wins += wins;
combinedRecs[teamIndex].losses += losses;
combinedRecs[teamIndex].ties += ties;
combinedRecs[teamIndex].total_points += total_points;
}
});
return allRecordsClone;
};
有什么想法嗎? 我無法弄清楚這一點。
通過 spread 復制數組仍然會創建對數組中包含的任何對象的引用。
const array1 = [1, {a: 2}, [3,4]]; const array2 = [...array1]; array2[0] = "unchanged in array1"; array2[1].a = "changed in both"; array2[2][0] = "arrays are Objects"; console.log('array1: ', array1); // array1: [1, {"a": "changed in both"}, ["arrays are Objects", 4]] console.log('array2: ', array2); // array2: ["unchanged in array1", {"a": "changed in both"}, ["arrays are Objects", 4]]
鑒於此,在推入組合數組之前,您需要使用Object.assign()
或傳播每個對象或數組。
React 文檔在這里介紹了這個問題: Immutability Helpers
@pilchard 的回答是正確的。 首先,您需要創建數組的每個屬性或元素的副本,然后將其推送到父組合數組。 您需要可以使用Object.assign()
或 spread 運算符來執行此操作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.