Reactjs:如何在组件之间共享 websocket

Reactjs: how to share a websocket between components

本文关键字:之间 共享 websocket 组件 Reactjs      更新时间:2023-09-26

我是 React 的新手,我在组件结构和它们之间共享 websocket 方面遇到了一些问题。

该应用程序由类别和产品组成。初始数据加载将通过 Ajax 请求完成,并且将使用 websocket 保持数据更新。

我的组件层次结构如下所示:

  • 分类列表
    • 类别
      • 产品列表
        • 产品
类别列表保存类别的状态

,产品列表保存类别内产品的状态。

所以我想在类别列表和产品列表中使用相同的 websocket,但侦听不同的 websocket 事件:类别:更新和产品:更新。

如何在组件之间共享 websocket,在哪里进行初始化的正确位置?

由于每个类别

都有一个产品列表,这是否意味着产品:更新事件将触发多次(每个类别一个)?我想就性能而言,这不是一件好事。

共享同一实例的另一种方法是简单地创建一个新文件,如下所示:socketConfig.js

import openSocket from 'socket.io-client';
const socket = openSocket("http://localhost:6600");
export default socket;

并在您想要的任何文件中使用它,只需导入它即可。

import socket from "../socketConfig";

这对我有用,因为我在 2 个不相互依赖的不同组件中使用它。

我建议在 CategoriesList 中初始化套接字连接,然后将连接作为 props 传递给子组件。当连接向下传递时,您应该能够使用它来侦听子组件中的特定事件。

这是 github 上使用 react 和 socket.io 的示例应用程序。套接字在父组件中初始化,然后向下传递。https://github.com/raineroviir/react-redux-socketio-chat/blob/master/src/common/containers/ChatContainer.js

在第 9 行初始化连接,然后在第 23 行作为 props 向下传递。该连接稍后在子组件中用于接收和发出事件。例如:https://github.com/raineroviir/react-redux-socketio-chat/blob/master/src/common/components/Chat.js

如果您使用的是 Redux Store,则将socket存储在 Redux Store 中,然后您可以从任何组件访问它,就像其他存储变量/状态一样。

组件

:A(在组件 A 中定义套接字)

//...
const dispatch = useDispatch();
useEffect(() => {
  const socket = io("http://localhost:8000");
  socket.on("connect", () => {
    console.log("Connected to Socket");
    dispatch({
      type: "INIT_SOCKET",
      socket: socket
    });
  });
}, [...]);

组件

:B(在另一个组件中使用套接字)

//...
const socket = useSelector(state => state.socket);
useEffect(() => {
  if (socket) {
    socket.on("msg", (data) => {
      console.log(data);
    });
  }
}, [socket]);

只需声明套接字外部组件,同样...

import SocketIOClient from 'socket.io-client';   
const socket=SocketIOClient('http://localhost:3000/chat')
function App() {
    //use socket here ...
    return (
        <div> </div>);
}

创建 socket.config.js 文件 为您的 websockets 添加打开连接。

export const WebSocket1 = new WebSocket('ws://YOUR websocketurl');
export const WebSocket2 = new WebSocket('ws://YOUR anotherwebsocketurl');

导入到您的任何组件中

import  {WebSocket1, WebSocket2}from '../../../utils/socket.config';

内部使用效果钩子利用websocket

 useEffect(() => {
WebSocket1.onopen = () => {
    WebSocket1.send(JSON.stringify(someData));
};
    WebSocket1.onmessage = (event: any) => {
      console.log(JSON.parse(event.data));
        
        
    }
    WebSocket1.onerror = error => {
        console.log(`WebSocket error: ${error}`);
    };
    WebSocket1.onclose = () => {
        console.log("disconnected");
    }
}, []);

参见 react-cent您可以编写自己的提供程序 (CentProvider.js) 来包装组件并通过上下文提供客户端。此外,编写高阶组件 (CentComponent.js) 以使其可用于this.props.<client>