![](/img/trans.png)
[英]How to pass correct state value into callback function inside useEffect hook?
[英]State variable hook not working with useEffect callback
嘗試在 React 功能組件中建立 websocket 連接,並使用鈎子更新 state 變量,如 [參考文獻 1] 所示:
export default function foo() {
const [ arr, setArr ] = useState([])
ws = useRef(null)
useEffect( () => {
ws.current = new Websocket('ws://example.com:1234')
ws.current.onmessage = (m) => {
setArr([...arr, m])
})
}, []) // Runs once at mount
}
arr
的 state 沒有保留。 它被覆蓋了。
注意我也試過將arr
傳遞給效果,就像這樣,但這導致了無限循環。 [參考文獻 2]。 隨着 arr 的更新,效果被稱為...
})
}, [arr])
}
舉個更具體的例子,取三個 websocket 消息:
['a']
['b']
['c']
更新后每條消息的預期 arr
['a']
['a', 'b']
['a', 'b', 'c']
結果:
['a']
['b']
['c']
為什么arr
不與回調中的setArr
掛鈎一起存儲? 為什么它是一個空數組?
參考
你有
useEffect( () => {
ws.current = new Websocket('ws://example.com:1234')
ws.current.onmessage = (m) => {
setArr([...arr, m])
})
}, []) // Runs once at mount
事實上,那里的效果掛鈎在掛載上運行一次——這就是問題所在。 當它運行時,附加的事件偵聽器在被觸發時運行以下行:
setArr([...arr, m])
為該處理程序使用 scope 中的arr
值。 由於處理程序僅附加一次,在掛載時, arr
的值始終相同; 初始 state,空數組。
請改用回調:
setArr(arr => [...arr, m])
我還建議用const
聲明ws
,以避免意外創建全局變量(並且可能將其wsRef
而不是ws
,這樣您就不會混淆套接字的 ref ):
const wsRef = useRef(null)
您可以嘗試使用數組的前一個 state 代替:
ws.current.onmessage = (m) => {
setArr(prevState => [...prevState, m])
}
對於setState
有兩種方法可以處理更改,第一種是給一個值作為參數,第二種是傳遞回調 function 。 它稱為更新程序 function,它提供 state 的先前值。在此處進一步了解setState
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.