在 React 中全局使用 Socket.IO?

Posted

技术标签:

【中文标题】在 React 中全局使用 Socket.IO?【英文标题】:Using Socket.IO in React globally? 【发布时间】:2021-02-08 17:29:02 【问题描述】:

我真的很想找到在全球客户端使用 socket.io 的解决方案。现在,我在使用我认为不正确的事件的每个页面和组件中调用下面的函数。我还想提一下,我正在使用 redux 来存储我的用户。

// Connect to Socket.IO
const socket = socketIOClient(process.env.REACT_APP_BASE_URL, 
  query: `type=client&id=$user_id`,
);

【问题讨论】:

一个选项可以是创建一个单例类并拥有一个套接字成员,然后将该类实例导入项目中的任何位置 【参考方案1】:

所以我这样做的方式是创建一个这样的 Socket 上下文文件

WebSocket.js

import React,  createContext  from "react";
import io from "socket.io-client";
// REDUX
import  bindActionCreators  from "redux";
import  connect  from "react-redux";
import  addOrder  from "./redux/actions";

const WebSocketContext = createContext(null);

export  WebSocketContext ;

const WebSocket = ( children, actions, user ) => 
  let socket;
  let ws;

  // EMIT EVENTS
  const newOrder = (data) => 
    socket.emit("newOrder", data);
  ;

  // ON EVENTS
  const newDriverAccepted = (callback) => 
    socket.on("newDriverAccepted", (driver) => 
      actions.addOrder(driver);
      callback(true);
    );
  ;

  if (!socket) 
    socket = io.connect(process.env.REACT_APP_BASE_URL, 
      query: `type=client&id=$user.id`,
    );

    ws = 
      socket: socket,
      newOrder,
      newDriverAccepted,
    ;
  

  return (
    <WebSocketContext.Provider value=ws>children</WebSocketContext.Provider>
  );
;

const mapDispatchToProps = (dispatch) => 
  const actions = 
    addOrder,
  ;
  return 
    actions: bindActionCreators(actions, dispatch),
  ;
;

const mapStateToProps = (state) => 
  return 
    user: state.clients.user,
  ;
;

export default connect(mapStateToProps, mapDispatchToProps)(WebSocket);

那我就这样用了

index.js

import WebSocketProvider from "./WebSocket";

ReactDOM.render(
  <Provider store=store>
    <PersistGate loading=null persistor=persistor>
      <WebSocketProvider>
        <App />
      </WebSocketProvider>
    </PersistGate>
  </Provider>,
  document.getElementById("root")
);

在这样的组件中

import React,  useContext  from "react";
import  WebSocketContext  from "../../WebSocket";

const MyComponent = () => 
    const socket = useContext(WebSocketContext);

    const handleNewOrder = () => 
         const data = ...
         socket.newOrder(data);
     
    return (
     ...
  )

【讨论】:

以上是关于在 React 中全局使用 Socket.IO?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Socket.io 在 React Native 移动应用程序中不起作用

在 create-react-app 中使用 Socket.io-client 的 WebSockets 代理

在使用 Node/React 验证 socket.io 连接时,您在哪里以及如何生成 JWT 令牌?

socket.io 监听器在功能性 React 中触发太多次

React.js JWT Socket.io 身份验证

Socket.io 将数据发送到全局变量