在我的 create-react-app 應用程式中,我使用 App.js 中的 useState 鉤子創建了一個物件,我將其作為引數傳遞給同一組件的 5 個不同實體。這個物件在簡單的數字屬性名稱下包含 5 個不同的陣列(所以它們很容易用 for 回圈迭代)。
const [ listObj, setListObj ] = useState({ 0: [], 1: [], 2: [], 3: [], 4: [] });
每個組件維護和修改其中一個陣列(對應于它的編號,所以組件 0 只修改組件 0,1 只修改 1 等),我使用函式來迭代 listObj 和里面的陣列,這樣我就可以比較它們的內容。
這些組件每個都有一個通過 App.js 傳遞給它們的唯一 componentNumber (0-4),以及一個 useEffect 鉤子,每次它們想要更新其特定陣列時,每個組件中看起來像這樣:
useEffect(() => {
let newArray = functionToGenerateSortedArrays();
let newListObj = { ...listObj, [ componentNumber ]: newArray };
setListObj( newListObj );
}, [ (all my state objects that trigger useEffect) ])
當我一次只更新與一個組件有關的內容時,這非常有用。問題是應用程式中有一個功能,所有組件都需要同時更新。似乎每個人都會獲取 listObj 的“舊”副本,使用它來創建具有更新資訊的 newListObj,然后使用 newListObj 呼叫 setListObj,從而覆寫其他組件嘗試進行的更改。唯一正確更新的 listObj 陣列是行中的最后一個。
當我嘗試實施這個 hacky 解決方案時,我認為自己非常聰明:
useEffect(() => {
let newArray = functionToGenerateSortedArrays();
setTimeout(() => {
let newListObj = { ...listObj, [ componentNumber ]: newArray };
setListObj( newListObj );
}, componentNumber * 100 );
}, [ (all my state objects that trigger useEffect) ])
不過這行不通。它實際上將 listObj 中的陣列立即切換回我想要的值,但在超時觸發后又恢復為錯誤的值。我不知道為什么,但如果有人有任何見解,我很想了解它。我想這可能與 React 如何“批量”更新狀態有關,但找不到關于如何阻止 React 這樣做的任何資訊,因此我可以測驗我的假設。
我是否有任何選項可以以“級聯”方式更改 listObj 中的陣列值,以便它們不會相互干擾?是否有另一種保存和更新狀態的方法不會產生此問題?非常感謝你花時間陪伴。
uj5u.com熱心網友回復:
這是給我們的狀態更新回呼形態的的useState鉤的setter:
useEffect(() => {
let newArray = functionToGenerateSortedArrays();
setListObj(currentListObj => {
// ^^^^^^^^^^^^^^
let newListObj = { ...currentListObj, [ componentNumber ]: newArray };
return newListObj;
});
}, [ (all my state objects that trigger useEffect) ])
這樣,即使將所有更新函式批處理在一起,它們也將接收當前值,而不是使用效果函式已關閉的過時值。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/352342.html
標籤:javascript 反应 反应钩子 使用效果 使用状态
上一篇:單擊按鈕時觸發回車鍵
下一篇:WEBPACK_IMPORTED_MODULE_3CollectionGroup不是函式-firebase集合組查詢嵌套資料
