你會發現,如果直接使用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...