簡體   English   中英

未使用 useState() 更新 React 狀態

[英]React state is not being updated using useState()

我想更新一個多維數組。
我有這個狀態變量。

const [travelledDataSet, setTravelledDataSet] = useState(JSON.parse(JSON.stringify(solidDataSet)));

實體數據集的結構最初是。

export const solidDataSet = [
    [
        [76.92025126928692, 31.815485031139886]
    ],
    [
        [76.92737521643127, 31.76427071949966]
    ],
    [
        [76.91587390417601, 31.75230203493911]
    ]
]

一旦觸發更新功能,我必須以時間間隔更新此數據。

const update=()=>{
        if(i>=dataSet[0].length) return;
        let tempData = JSON.parse(JSON.stringify(travelledDataSet));
        tempData[0].push(dataSet[0][i]);
        setTravelledDataSet(tempData);
        i++; // increment to next position
        setTimeout(update,100)
    }

雖然狀態更新,但travelledDataSet[0]的大小仍然是 2。而且, travelledDataSet[0][1]只是在更新。
例如

// first__update__is
// -- travelledDataSet[0] --
[76.92025126928692, 31.815485031139886]
[77.06221522802589, 31.75536733328293]

// in__second__update
// --travelledDataSet[0]--
[76.92025126928692, 31.815485031139886]
[77.0603269528807, 31.75317784482199] -- only this is being updated each time. 

為了檢查為什么這不起作用,我在更新函數之外創建了另一個變量(不是反應狀態)。

let ar=JSON.parse(JSON.stringify(travelledDataSet))
    const update=()=>{
        if(i>=dataSet[0].length) return;
        let tempData = JSON.parse(JSON.stringify(travelledDataSet));
        tempData[0].push(dataSet[0][i]);
        ar[0].push(dataSet[0][i]);
        console.log("AR: ",ar[0],"Data:",travelledDataSet[0]); // ---- this is updating
        setTravelledDataSet(tempData);
        i++; // increment to next position
        setTimeout(update,10)
    }

函數完成后,這個代碼console.log("AR: ",ar[0],"Data:",travelledDataSet[0])打印出來。 在此處輸入圖片說明

您可以在下圖中看到, ar[0]的長度為 58,而travelledDataSet[0]長度僅為 1。

即使這也不起作用setTravelledDataSet(JSON.parse(JSON.stringify(tempData)));

可重現的代碼:

// it will render solid route indecating traveled route
    const [travelledDataSet, setTravelledDataSet] = useState(JSON.parse(JSON.stringify(solidDataSet)));
    // update route -- only in development for simulation purpose
    let i = 1;
    const update=()=>{
        if(i>=dataSet[0].length) return;
        let tempData = JSON.parse(JSON.stringify(travelledDataSet));
        tempData[0].push(dataSet[0][i]);
        setTravelledDataSet(JSON.parse(JSON.stringify(tempData)));
        i++; // increment to next position
        setTimeout(update,10)
    }
    useEffect(()=>{
        setTravelledDataSet(JSON.parse(JSON.stringify(solidDataSet)));
        if(display)
            update()
    },[display])

每當display發生變化時,我都必須從一開始就做同樣的事情。 該組件大約有數千行代碼。 我在這里添加了可以簡要解釋問題的代碼。

你為什么要遞歸定時調用更新; update()調用setTimeout(update, 10) update() 我以前沒見過這個成語,看起來很腥。 也許看看setInterval

還可以考慮使用useEffect鈎子來處理數據更改時的副作用,而不是箭頭函數。

我認為你應該重構這段代碼。 很難閱讀。

您的“循環計數器” i會在每個渲染周期重新聲明,即每次組件渲染時i等於 1。

由於我仍然不清楚為什么狀態如此復雜以及您的狀態更新在這里試圖完成的事情是我認為可能是一個簡單的“修復”。 使用i循環計數作為傳遞的參數,並在啟動遞歸時最初傳遞1 您還應該將update函數聲明移動到useEffect鈎子中以將其作為依賴項刪除。

useEffect(() => {
  const update = (i) => { // <-- consume i loop counter
    if(i >= dataSet[0].length) return;

    const tempData = JSON.parse(JSON.stringify(travelledDataSet));
    tempData[0].push(dataSet[0][i]);
    setTravelledDataSet(JSON.parse(JSON.stringify(tempData)));
    
    setTimeout(() => update(1 + 1), 10); // <-- increment i
  }

  setTravelledDataSet(JSON.parse(JSON.stringify(solidDataSet)));

  if (display) {
    update(1); // <-- initial seed 1
  }
}, [display])

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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