ReactJS + Socket.IO - 处理套接字连接的最佳方法

时间:2018-02-14 19:36:46

标签: node.js reactjs sockets socket.io

我试图使用Node和Socket.IO创建一个ReactJS实时应用程序,但是我很难找到在客户端处理套接字连接的最佳方法。

我有多个React组件,都需要来自服务器的一些信息,最好通过套接字连接实时。但是当导入socket.io-client依赖关系并在不同文件中建立与服务器的连接时,我会获得与服务器的多个连接,这看起来并不是最佳的。

因此,我想知道是否有更好的解决方案来共享多个组件之间的连接,而无需为每个组件创建新连接。也许通过在主app.js文件中建立连接,然后将其传递给子组件以供以后使用。

网上有些地方建议使用context属性来传递套接字变量,但是React自己的文档highly discourage the use of context

以下代码只是一个示例,而不是实际代码,因为实际项目中的代码比说明问题所需的代码要多得多。

foo.js

import React from 'react';
import io from 'socket.io-client';

const socket = io("http://localhost:3000");

class Foo extends React.Component {
    // ...
    componentDidMount() {
        socket.on("GetFooData", (data) => {
            this.setState({
                fooData: data
            });
        });
    }
    // ...
}

bar.js

import React from 'react';
import io from 'socket.io-client';

const socket = io("http://localhost:3000");

class Bar extends React.Component {
    // ...
    componentDidMount() {
        socket.on("GetBarData", (data) => {
            this.setState({
                barData: data
            });
        });
    }
    // ...
}

app.js

import React from 'react';
import ReactDOM from 'react-dom';
import Foo from './foo';
import Bar from './bar';

const App = () => {
    return (
        <div className="container">
            <Foo />
            <Bar />
        </div>
    );
};

ReactDOM.render(
    <App />,
    document.getElementById("root")
);

2 个答案:

答案 0 :(得分:2)

您可以创建一个套接字连接,然后像这样导出它,

import io from "socket.io-client";
let socket = io("http://localhost:8000/chat");
export default socket;

然后将其导入任何地方

import socket from "../../socket/socket";

答案 1 :(得分:1)

旧问题,但让我为Google员工回答。

我也在考虑上下文,但是去通过它作为道具,但是发生了一个问题,由于反应路线,我实际上无法按照我想要的方式传递它。路由道具(例如重定向历史记录)不起作用,或者套接字连接未通过。

因此,解决方案实际上是将socket变量作为道具传递,但结构有所不同。如果您使用的是路线,则会添加其他内容。实际上,您实际上需要以一种不同的方式呈现组件。

对我来说,这段代码

<Route path="/game" component={Game} />} />

更改为

<Route path="/game" render={(props) => <Game {...props} socket={this.state.socket} />} />

对于连接套接字,我像这样在componentWillMount内部完成。

  constructor(props) {
    super(props);
    this.state = {
      socket: false,
    }
  }
  componentWillMount() {
    let socket = io("http://localhost:5000");
    this.setState({socket});
  }

编辑:很显然,这并不是最好的方法,当通过套接字连接时,有些东西根本无法工作,例如套接字和express之间的相同会话。