javascript - 具有功能组件的 WebSockets

标签 javascript reactjs react-hooks

我在我的 React 应用程序中使用 websockets。该应用程序应该只包含功能组件。

假设该应用程序包含两个“选项卡”:一个不相关,另一个是使用 websockets 的聊天。鉴于此,我们希望在用户进入聊天选项卡后启动一个 websocket 连接。

组件应该如何处理 websocket 对象?因为我们想要在用户切换回另一个选项卡 (WebSocket.close()) 时进行清理,所以听起来我们应该在这里使用效果 Hook 。

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

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

最佳答案

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

The useRef() Hook isn’t just for DOM refs. The “ref” object is a generic container whose current property is mutable and can hold any value, similar to an instance property on a class. more

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

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

关于javascript - 具有功能组件的 WebSockets,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58432076/

相关文章:

reactjs - 在复选框单击上 react 更新获取

javascript - 如何知道ckeditor中是否按下了alt键?

javascript - 如何使用gulp安装bower

javascript - 边框使 li 内的内容移位

javascript - 我正在尝试获取我的 json 站点以启用 API,但出现错误 "Unexpected token < in JSON at position 0"

javascript - 我应该使用 useselector/useDispatch 而不是 mapStateToProps

javascript - 如何继承EventTarget对象?

javascript - Ant Design 中的Rangepicker 的值如何获取?

javascript - 在 React 中验证电子邮件最简单、最快捷的方法是什么?

javascript - React : If a useState is updated, 怎么可能同时不更新呢?