簡體   English   中英

State 變量掛鈎不適用於 useEffect 回調

[英]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掛鈎一起存儲? 為什么它是一個空數組?

參考

  1. 具有功能組件的 WebSockets
  2. https://github.com/facebook/react/issues/14066

你有

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM