[英]Issue with React useState 2D array
我正面臨 useState 的奇怪行為。 在沙箱https://codesandbox.io/s/elastic-ellis-gjre7 中,我有 3 個輸入字段,如果單擊它們會更改值。 問題出在我登錄控制台的歷史記錄 state 上。
預期的行為是,只要您單擊其中一個框,它就會將所有 3 個框的 state 保存在歷史數組中,當我們單擊另一個時,它會在歷史數組中添加新的展示位置。
單擊 1 框時,它可以正常工作 - “歷史 1”顯示位置,“歷史 2”和“歷史 3”未定義。
但是當我們點擊第二個框時,它開始變得奇怪——它重寫了之前寫的“歷史1”,所以現在“歷史1”和“歷史2”的內容是一樣的。 奇怪,因為我們所做的只是將新值連接到歷史數組,但它會覆蓋以前的值。
誰能解釋一下,為什么它會這樣?
你應該這樣寫:
setHistory((prevHistory) => prevHistory.concat({ ...placements }));
說明:我相信您正在做的是將以前的 state 與當前的合並,據我了解,您想聯系 arrays - 如果錯了,請糾正我 -
在第 16 行, newValue[event.value.id]
正在發生變異。 意思是,在history
的每個元素中都在更新和引用相同的值。
為了達到預期的行為,解決方案是引用不同的值。 這可以通過克隆來實現。
有關實際示例,請參閱沙箱的這個分支。
// Mutation.
newValue[event.target.id].value = "X";
// Cloning.
const targetId = event.target.id
newValue[targetId] = {...newValue[targetId], value: "X"};
你有幾件事錯了。
您將 item.id 用作 event.target.id,但您正在根據展示位置的數組索引進行更新,您最終會得到無法預料的結果。
您正在根據展示位置 state 更新歷史記錄,但在更新歷史記錄時,新展示位置可能尚未准備好。
在這里,我們將根據您的商品 ID 而不是索引來更新您的展示位置。 然后我們同時使用新的展示位置更新歷史記錄。
const handleClick = (event) => {
// .map is commonly used in this type of situation to update the correct object in the array with new value.
const newplacement = placements.map(item => item.id === parseInt(event.target.id) ? { ...item, value: 'X'} : item )
setPlacements(newplacement);
setHistory((prevHistory) => [...prevHistory, newplacement]);
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.