關於setState使用的一些坑

2022-06-24 07:54:07 字數 2761 閱讀 8658

你會發現,如果直接使用push等方法改變state,按理來說,push會改變原陣列,陣列應該更新,但渲染出來的state並不會更改

let newvalue = 1;

const [array, setarray] = usestate();

const handlechange = (newvalue: number) =>

render:

this array is

//

這是由於js中,陣列的賦值是引用傳遞的,array.push相當於直接更改了陣列對應的記憶體塊,但react內部用於對比的array的記憶體並沒有更改,是指向同乙個記憶體的,setstate只做shallow compare,因此沒有觸發re-render。

可以使用擴充套件運算子,建立乙個新陣列,更改記憶體引用

const handlechange = (newvalue: number) =>

render:

this array is

//[1]

或者觸發展示元件的re-render,這樣即使不改變陣列的引用,依然可以正確顯示變動。

const handlechange = (newvalue: number) =>

render:

this array is

//[1]

再給乙個直觀的例子(感謝我的同事@ling)

直接嘗試:

const  = react

const usememorystate = (init) =>

return [arr, updatearr, lastarrref.current]

}let i = 0;

const [arr, setarr, lastarr] = usememorystate([0])

const [updatesign, setupdatesign] = usestate(false)

return(

<>

current array :

setarr(arr.push(i) && arr)

} classname="btn btn-2 btn-2c">

try it

setarr(arr.push(i) && [...arr])
} classname="btn btn-2 btn-2c">

try it

setarr(arr.push(i) && arr); setupdatesign(x => !x)
}}

classname="btn btn-2 btn-2c">

try it);}

逐次點選第二個按鈕或第三個按鈕都可以正常更新渲染。

點選第乙個按鈕,通過console可以看出來,array陣列值有更新,但沒有渲染(current array 沒變);再點其他兩個按鈕時,會把第乙個按鈕點選更新的結果一起渲染出來。

側面展示並不是沒有更新陣列,而是更新後未渲染。

setstate某種意義上是類似於非同步函式的。

// name is ""

this.setstate()

console.log(`name is $`)

這樣寫,name是不能正常顯示。

最常用的辦法就是使用**函式

this.setstate(, () => `)

})

setstate的「非同步」是本身執行的過程和**是同步的,只是合成事件和鉤子函式的呼叫順序在更新之前,導致在合成事件和鉤子函式中沒辦法立馬拿到更新後的值,形成了所謂的非同步。批量更新優化也是建立在「非同步」之上的,如果對同乙個值進行多次setstate,setstate的批量更新策略會對其進行覆蓋,取最後一次執行;如果是同時setstate多個不同的值,在更新時會對其合併批量更新。

useeffect(() =>  as trainingmodel;

setmodels([...models, newmodel]);

starttraining(newmodel);

}, [props.datasetid]);

const starttraining = async (newmodel: trainingmodel) => ;

類似的,老生常談的,在useeffect裡面設定乙個interval,過了interval time,也同樣是useeffect更新時的state值,而得不到最新的state值。

為解決非同步導致的獲取不到最新state的問題,使用setstate的**函式獲取state的當前最新值

const starttraining = async (newmodel: trainingmodel) => );

};

原因是,元件內部的任何函式,包括事件處理函式和effect,都是從它被建立的那次渲染中被[看到]的,也就是說,元件內部的函式拿到的總是定義它的那次渲染中的props和state。想要解決,一般兩種方法,一種是上述的使用setstate**函式獲取state最新值,一種是使用ref儲存修改並讀取state。

關於pandas的一些使用

該函式只對dataframe或series型別有效,用於去除重複值。引數有三個 舉個例子 dataframe pd.read excel data.xlsx dataframe2 pd.read excel data.xlsx dataframe.drop duplicates subset non...

關於jqgrid的一些使用

1.jqgrid如何切換中英文 在做電力監控系統的時候,根據專案的需要涉及到中英文的切換,一直糾結了好久沒有好的辦法,雖然我知道可以手動更改引入的js檔案就可以更改中英文,但是動態的一直沒有辦法更改,最後想到了乙個辦法就是講jqgrid框架中的js i18n grid.locale cn.js的資料...

關於Fragment使用的一些見解

下面來看一下我自定義的fragment的 public abstract class myfragment extends fragment public myfragment getparentmyfragment public void showfragments myfragment myfr...