为啥 useState() 会重复 websocket 事件?
Posted
技术标签:
【中文标题】为啥 useState() 会重复 websocket 事件?【英文标题】:Why does useState() duplicate websocket events?为什么 useState() 会重复 websocket 事件? 【发布时间】:2019-09-05 16:13:58 【问题描述】:我的反应组件正在通过 websocket 从服务器接收消息。当我尝试使用 useState() 更新状态时,套接字会重复。
如果我这样做......
import React, useState from 'react'
export default () =>
let[message, setMessage] = useState()
let ws = new WebSocket("ws://blah");
ws.onmessage = (e) =>
let obj = JSON.parse(e.data);
// event name
console.log(obj.event);
// event data
console.log(obj.value);
// setMessage(obj.value)
ws.close
return <div>
message
</div>
然后控制台按预期显示每条消息
但如果我在setMessage(object.value)
中回复评论,那么每条消息的所有连接都会重复
setMessage() 不知何故导致连接累积
【问题讨论】:
【参考方案1】:那是因为您在每次渲染时都创建了一个新的 websocket。
由于连接到网络套接字是一种“副作用”,您需要使用useEffect
import React, useState from 'react'
export default () =>
let [message, setMessage] = useState()
React.useEffect(() =>
let ws = new WebSocket("ws://blah");
ws.onmessage = (e) =>
let obj = JSON.parse(e.data);
// event name
console.log(obj.event);
// event data
console.log(obj.value);
setMessage(obj.value);
;
return () =>
ws.close()
, [])
return (
<div>
message
</div>
);
【讨论】:
感谢@Galupuf 修复了它。 感谢@Galupuf 修复了它。【参考方案2】:或者,您可以将 websocket 声明 移出函数。这样,您可以在useEffect
以外的任何地方使用它:
import React, useState from 'react'
import w3cwebsocket as W3CWebSocket from 'websocket';
const ws = new W3CWebSocket("ws://blah");
export default () =>
let [message, setMessage] = useState()
React.useEffect(() =>
ws.onmessage = (e) =>
//...
setMessage(obj.value);
;
return () =>
ws.close()
;
, []);
return (
<div>
message
</div>
);
;
【讨论】:
以上是关于为啥 useState() 会重复 websocket 事件?的主要内容,如果未能解决你的问题,请参考以下文章
React hooks:为啥异步函数中的多个 useState 设置器会导致多次重新渲染?
为啥 setState 回调会抛出错误:“来自 useState() 和 useReducer() Hooks 的状态更新不支持第二个回调参数...”