13

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")
);
4
  • Doesn't React encourage the use of stores? I would think there would be some kind of way to compose a react store that leverages an Observable that wraps a WebSocket. Commented Feb 14, 2018 at 19:39
  • @zero298 Would that be with the use of Redux? Commented Feb 14, 2018 at 23:58
  • Create a socket in App.js(root component) and pass the data to child components as props or by using redux. Commented Jun 22, 2018 at 22:30
  • For simplicity you can use props/state. Just use the componentWillMount in the root component, then pass the state as props to child components. I've just done this myself and works fine Commented Jul 18, 2018 at 15:07

1 Answer 1

24

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";
Sign up to request clarification or add additional context in comments.

2 Comments

If you have set up a counter and have 7-20+ random connections that you are trying to figure out, and have socket connections set up through components or through context, remove those and use this, cleared up all my random connections. Make sure you have a cleanup function too! example: return () => socket.close() Thank you jsRook, helped me out more so much. Sometimes it's best to go back to basics :)
Amazing, thanks. Is it a good practice to have this on index.js in react?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.