我在我的React应用程序中使用了websockets,这个应用程序应该只包含功能组件。
假设应用程序由两个“选项卡”组成:一个是无关的,另一个是使用websocket的聊天。2考虑到这一点,我们希望在用户进入聊天选项卡后立即建立websocket连接。
组件应该如何处理WebSocket对象?因为我们希望在用户切换回另一个标签页(WebSocket.close()
)时进行清理,所以听起来我们应该在这里使用一个effect钩子。
const Chat = () => {
const [messages, setMessages] = useState([]);
useEffect(() => {
const webSocket = new WebSocket("ws://url");
webSocket.onmessage = (message) => {
setMessages(prev => [...prev, message.data]);
};
return () => webSocket.close();
}, []);
return <p>{messages.join(" ")}</p>;
};
但是现在,假设我们想在useEffect
作用域之外的某个地方引用webSocket
变量--比如说,我们想在用户单击按钮时向服务器发送一些信息。
现在,应该如何实施呢?我目前的想法(尽管我觉得有缺陷)是:
const Chat = () => {
const [messages, setMessages] = useState([]);
const [webSocket] = useState(new WebSocket("ws://url"));
useEffect(() => {
webSocket.onmessage = (message) => {
setMessages(prev => [...prev, message.data]);
};
return () => webSocket.close();
}, []);
return <p>{messages.join(" ")}</p>;
};
挺管用的,不过我觉得有更好的解决办法。
2条答案
按热度按时间92dk7w1h1#
正如@skyboyer在你的问题下面的评论中所写的,你可以使用
useRef
钩子来保持WebSocket
,这会更正确,因为你不打算改变或重新创建WebSocket对象。useRef()Hook不只是用于DOM引用,“ref”对象是一个泛型容器,它的当前属性是可变的,可以保存任何值,类似于类的示例属性。
因此,您可以将代码更改为:
dzhpxtsq2#
也许一个好的选择是在一个单独的WS示例中管理WS操作,并在需要的地方使用它。
所以在你的组件里。
用这种方法总是返回相同的示例。