本文介绍了带有功能组件的 WebSockets的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的 React 应用程序中使用 websockets.应用程序应该仅由功能组件组成.

想象一下应用程序由两个标签"组成:一个不相关,另一个是使用 websockets 的聊天.鉴于此,我们希望在用户进入聊天选项卡后建立一个 websocket 连接.

组件应该如何处理websocket对象?由于我们希望在用户切换回另一个选项卡时进行清理(WebSocket.close()),因此听起来我们应该在这里使用效果挂钩.

const Chat = () =>{const [messages, setMessages] = useState([]);useEffect(() => {const webSocket = new WebSocket("ws://url");webSocket.onmessage = (message) =>{setMessages(prev => [...prev, message.data]);};返回 () =>webSocket.close();}, []);返回 <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]);};返回 () =>webSocket.close();}, []);返回 <p>{messages.join(" ")}</p>;};

有点管用,不过我觉得有更好的解决方案.

解决方案

正如@skyboyer 在您的问题下的评论中所写,您可以使用 useRef 钩子来保存 WebSocket 它会更正确,因为您不会更改或重新创建 WebSocket 对象.所以你不需要 useState 钩子.

useRef() 钩子不仅仅用于 DOM 引用.ref"对象是一个通用容器,它的当前属性是可变的并且可以保存任何值,类似于类上的实例属性.更多

因此您可以将代码更改为:

const Chat = () =>{const [messages, setMessages] = useState([]);const webSocket = useRef(null);useEffect(() => {webSocket.current = new WebSocket("ws://url");webSocket.current.onmessage = (message) =>{setMessages(prev => [...prev, message.data]);};返回 () =>webSocket.current.close();}, []);返回 <p>{messages.join(" ")}</p>;};

I'm using websockets in my React application. The application is supposed to consist of function components only.

Imagine the application consists of two "tabs": one irrelevant, and the other one, a chat using websockets. Given that, we want to whip up a websocket connection once the user enters the chat tab.

How should the component handle the websocket object? Since we want to clean up once the user switches back to the other tab (WebSocket.close()), it sounds like we should be using an effect hook here.

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>;
};

Works! But now, imagine we want to reference the webSocket variable somewhere outside the useEffect scope - say, we want to send something to the server once the user clicks a button.

Now, how should it be implemented? My current idea (albeit a flawed one, I feel) is:

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>;
};

Kinda works, nevertheless I feel like there's a better solution.

解决方案

As @skyboyer has written in a comment under your question, you could use useRef hook to hold WebSocket and it will be more correct since you are not going to change or recreate WebSocket object. So you don't need useState hook.

So you could change your code to:

const Chat = () => {
    const [messages, setMessages] = useState([]);
    const webSocket = useRef(null);

    useEffect(() => {
        webSocket.current = new WebSocket("ws://url");
        webSocket.current.onmessage = (message) => {
            setMessages(prev => [...prev, message.data]);
        };
        return () => webSocket.current.close();
    }, []);
    return <p>{messages.join(" ")}</p>;
};

这篇关于带有功能组件的 WebSockets的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-13 04:11