Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reactjs: how to share a websocket between components

I'm new to React and I'm having some issues regarding components structure and sharing a websocket between them.

The app consists of categories and products. The initial data load will be done with an Ajax request and a websocket will be used keep data updated.

My component hierarchy looks like this:

  • CategoriesList
    • Category
      • ProductsList
        • Product

CategoriesList holds the state of categories and ProductsList holds the state of products within a category.

So I would like to use the same websocket inside CategoriesList and ProductsList but listening to different websocket events: category:updated and product:updated.

How do I share the websocket between components and where is the right place to initialize it?

Since there is one ProductsList for each Category, does this means that the products:updated event will fire multiple times ( one for each category )? I guess this isn't a good thing in terms of performance.

like image 740
Fernando Avatar asked Mar 20 '16 21:03

Fernando


People also ask

How do you use WebSockets in React?

Basic Setup for React First of all, we create a new instance of the WebSocket as a class property ws . Then in the componentDidMount method we can subscribe and listen to some events provided to us by WebSocket. onopen : The onopen event listener is called when the WebSocket connection is established.

How many ways we can communicate between components in React?

I saw that the question is already answered, but if you'd like to learn more details, there are a total of 3 cases of communication between components: Case 1: Parent to Child communication. Case 2: Child to Parent communication. Case 3: Not-related components (any component to any component) communication.


2 Answers

Another way of sharing the same instance is simply create a new file as below: socketConfig.js

import openSocket from 'socket.io-client';

const socket = openSocket("http://localhost:6600");

export default socket;

and the use it in any file you want, just import it.

import socket from "../socketConfig";

This works for me, as I use it in 2 different components which are not depend on each other.

like image 132
Rufat Gulabli Avatar answered Sep 17 '22 12:09

Rufat Gulabli


If you are using Redux Store, then store the socket in Redux Store and then you can access it from any component as like other store variable/state.

Component: A (Defining Socket in Component 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
    });
  });
}, [...]);

Component: B (Using Socket in another Component)

//...
const socket = useSelector(state => state.socket);

useEffect(() => {
  if (socket) {
    socket.on("msg", (data) => {
      console.log(data);
    });
  }
}, [socket]);
like image 27
Mitanshu Avatar answered Sep 16 '22 12:09

Mitanshu