ReactJS + Socket.IO - Best way to handle socket connection

假如想象 提交于 2020-08-02 08:13:41

问题


I'm trying to make a ReactJS realtime application with Node and Socket.IO, but I'm having a hard time figuring out the best way to handle my socket connection on the clientside.

I have multiple React components that all need some information from the server, and preferrably in realtime via the socket connection. But when importing the socket.io-client dependency and making the connection to the server in different files, I get multiple connections to the server, which doesn't really seem that optimal.

So I'm wondering if there's a better solution to share the connection between multiple components without having to create a new connection for each component. Maybe by making connection in the main app.js file and then passing it onto the child components for later use.

Some places online suggests using the context property to pass the socket variable, but React's own documentation highly discourage the use of context.

The following code is just an example, not the actual code since there's much more unnecessary code in the real project than needed to illustrate the problem.

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")
);

回答1:


You can create one socket connection and then export it ,like this,

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

and then import it anywhere

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



回答2:


Old question, but let me answer this for the googlers.

I was also considering the context, but instead went for passing it as a props, but a problem happened where I couldn't actually pass it the way I wanted due to react-route. Either the route props (such as history to redirect) didn't work or the socket connection didn't get passed.

So the solution is actually passing the socket variable as a props, but with having a bit of a different structure. In case you are using a route it adds another thing. You actually need to render the component in a kinda different way.

So for me, this code

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

changes to

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

As for connecting the socket I do it inside the componentWillMount like so.

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

Edit: Well apparently this isn't really the best way, when passing the socket connection some stuff simply don't work such as same session between socket and express.



来源:https://stackoverflow.com/questions/48794919/reactjs-socket-io-best-way-to-handle-socket-connection

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!