[英]Getting previous State of useState([{}]) (array of objects)
我正在努力獲得我輸入的真正以前的 state。 我認為我在寫這篇文章時發現的真正問題是我使用const inputsCopy = [...inputs]
總是認為這會創建一個深層副本並且我不會改變原始數組。
const [inputs, setInputs] = useState(store.devices)
store.devices 看起來像這樣
devices = [{
name: string,
network: string,
checked: boolean,
...etc
}]
我試圖在輸入更改后使用自定義掛鈎來獲取先前的值。 我正在嘗試檢查檢查的值是否已從真/假切換,因此我無法在 useEffect 掛鈎中運行我的自動保存功能。
function usePrevious<T>(value: T): T | undefined {
// The ref object is a generic container whose current property is mutable ...
// ... and can hold any value, similar to an instance property on a class
const ref = useRef<T>();
// Store current value in ref
useEffect(() => {
ref.current = value;
}); // Only re-run if value changes
// Return previous value (happens before update in useEffect above)
return ref.current;
}
我還嘗試了另一個自定義掛鈎,它與 useState 類似,但具有 prev state 的第三個返回值。 看起來像這樣。
const usePrevStateHook = (initial) => {
const [target, setTarget] = useState(initial)
const [prev, setPrev] = useState(initial)
const setPrevValue = (value) => {
if (target !== value){ // I converted them to JSON.stringify() for comparison
setPrev(target)
setTarget(value)
}
}
return [prev, target, setPrevValue]
}
在我從 api 獲取數據后,這些鈎子顯示了正確的 prevState,但是任何輸入更改都將 prev state 設置為相同的 prop 值。 我認為我的問題出在 mobx store.devices 的某個地方,我將初始 state 設置為,或者我在無法以某種方式復制/變異 state 時遇到問題。 我還嘗試檢查 setState 中的 prevState 是什么
setInputs(prev => {
console.log(prev)
return inputsCopy
})
寫完后,我認為我的問題可能是當輸入值發生變化並且 onChange 轉到我的 handleInputChange function 我創建了 state 輸入的副本,例如
const inputsCopy = [...inputs]
inputsCopy[i][prop] = value
setInputs(inputsCopy)
出於某種原因,我認為這會一直創建一個深層副本。 過去我在使用 redux 和其他一些事情時遇到過問題,我認為我沒有改變原始變量。
為所有回復干杯!
編輯:澄清我為什么要變異(不是我想要的)我在多個組件中有很多用於配置設備設置的輸入。 問題是我如何設置我的 onChange 函數<input type="text" value={input.propName} name="propName" onChange={(e) => onInputChange(e, index)} />
const onInputChange = (e, index) => {
const value = e.target.value;
const name = e.target.name;
const inputsCopy = [...inputs]; // problem starts here
inputsCopy[index][name] = value; // Mutated obj!?
setInputs(inputsCopy);
}
這就是我認為我的自定義 prevState 鈎子不起作用的原因。 因為我正在變異它。
我的 AUTOSAVE 功能,我想要 DIFF 來比較 prevState 和 current
const renderCount = useRef(0)
useEffect(() => {
renderCount.current += 1
if (renderCount.current > 1) {
let checked = false
// loop through prevState and currentState for checked value
// if prevState[i].checked !== currentState[i].checked checked = true
if (!checked) {
const autoSave = setTimeout(() => {
// SAVE INPUT DATA TO API
}, 3000)
return () => {
clearTimeout(autoSave)
}
}
}
}, [inputs])
抱歉,我必須從 memory 中全部輸入。 不在辦公室。
如果我理解您的問題,您正在嘗試從之前的 state 值更新 state 並避免突變。 const inputsCopy = [...inputs]
只是數組的淺拷貝,所以元素仍然引用前一個數組。
const inputsCopy = [...inputs] // <-- shallow copy
inputsCopy[i][prop] = value // <-- this is a mutation of the current state!!
setInputs(inputsCopy)
Use a functional state update to access the previous state, and ensure all state, and nested state, is shallow copied in order to avoid the mutations. 使用Array.prototype.map
制作inputs
數組的淺表副本,使用迭代索引匹配您要更新的特定元素,然后還使用擴展語法制作該元素 object 的淺表副本,然后覆蓋[prop]
屬性值。
setInputs(inputs => inputs.map(
(el, index) => index === i
? {
...el,
[prop] = value,
}
: el
);
雖然這是一個 Redux 文檔,但不可變更新模式文檔是一個很好的解釋和示例。
摘抄:
更新嵌套對象
更新嵌套數據的關鍵是必須適當地復制和更新每一層嵌套。 對於那些學習 Redux 的人來說,這通常是一個困難的概念,並且在嘗試更新嵌套對象時經常會出現一些特定的問題。 這些會導致意外的直接突變,應該避免。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.