簡體   English   中英

React useState 2D 數組的問題

[英]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"};

你有幾件事錯了。

  1. 您將 item.id 用作 event.target.id,但您正在根據展示位置的數組索引進行更新,您最終會得到無法預料的結果。

  2. 您正在根據展示位置 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM