![](/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.