What could be causing my socket to enter a never-ending loop?

Client Side Code:

useEffect(() => {
    socketRef.current = io.connect("...", { transports : ['websocket'] })
    socketRef.current.emit("online", id)

    socketRef.current.on("message", ({ name, message }) => {
        setChat([ ...chat, { name, message , system: false } ])
    })

    /* Removed code for online and offline events */

    return () => {
        socketRef.current.disconnect()
    }
},[ chat ])

Server Side Code:

io.on('connection', socket => {
  socket.on('message', ({ name, message , userID }) => {
    io.emit('message', { name, message , userID })
  })

  socket.on('online', ( userID ) => {
    onlineApprovers.push({ user: userID , id: socket.id })

    console.log(userID + ' is online')
    io.emit('online', userID)
  })

  socket.on('disconnect', () => {
    console.log(onlineApprovers.find(a => a.id === socket.id).user + ' is offline')
    io.emit('offline', onlineApprovers.find(a => a.id === socket.id).user)
  })
})

Description of functionality: Upon user visiting the site, their user id is obtained, an 'online' event is emitted to the backend which logs that user is online. When user leaves the site, socket disconnects and logs the user as offline.

The issue arises on the frontend where it enters an infinite loop, continuously logging 'userID is online' followed by 'userID is offline' even without closing the window.

/ edit /

Removing the code related to online and offline events stopped the infinite loop, however it broke the frontend's ability to receive data from the backend.

Answer №1

Whenever a user enters or the status of the chat changes, an online event is sent to the server, triggering the server to broadcast an online event to all connected clients. This event then triggers the following listener:

socketRef.current.on("online", ( userID ) => {
  setChat([ ...chat, { name: userID , message: `has logged on` , system: true } ])
})

Since setChat() is called here with a new array as parameter, the React component re-renders, causing the useEffect function to execute again. Consequently, the online event is fired once more, creating a loop.

A better approach would be to establish the socket connection when the component mounts by passing [] as a dependency for useEffect(). Utilize the setChat() state updater function to access the most recent value of chat:

useEffect(() => {
  socketRef.current = io.connect("...", { transports : ['websocket'] });
  socketRef.current.emit("online", id);

  socketRef.current.on("message", ({ name, message }) => {
    setChat(chat => [ ...chat, { name, message , system: false } ]);
  });

  socketRef.current.on("online", ( userID ) => {
    setChat(chat => [ ...chat, { name: userID , message: `has logged on` , system: true } ]);
  });

  socketRef.current.on("offline", ( userID ) => {
    setChat(chat => [ ...chat, { name: userID , message: `${userID} has logged off` , system: true } ]);
  });

  return () => {
    socketRef.current.disconnect();
  };

}, []);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Executing two distinct SQL queries within one nodejs function

I'm facing an issue with updating two tables in my database - the stockmaster table and the prodstock table. I've been trying to run a query using a function to update both tables simultaneously, but unfortunately, it's not working as expect ...

Is it possible to include pseudo element elements in the configuration of a custom theme in Material UI?

Within my file themeConfig.js, I have defined several theme variables that are utilized to style different components throughout my application. Among these variables, there is a need for implementing the -webkit scrollbar styles for certain components. Du ...

Arranging misshapen circles on the exterior of a sphere

My current project involves utilizing Three.js to position circles of various sizes evenly across the surface of a sphere, inspired by the concept seen in the periodic table of elements example. Despite extensive research efforts, I've come to the re ...

Having trouble getting the expected transition effects to work with Vue.js

Currently, I have a display of lists of items through the use of v-for. Initially, only the summary section of each item is visible. Upon clicking on an item, the details section is supposed to appear. This functionality is achieved by adding or removing ...

Having trouble with validation messages not displaying correctly in Angular after removing a value. What is the correct approach to fix this issue

I've encountered an issue with Angular validation where it's triggering validation on page load, which is not desired. Additionally, when I enter a value, the validation message disappears, but if I return to the textbox and delete the input, the ...

Having trouble properly removing an item from an array using splice() function

I'm facing an issue with an array where I need to remove a specific object. I attempted using the splice() method, but upon implementation, it ends up removing all objects except the one that was found. Here's a snippet of my JavaScript code: On ...

When the object contains multiple arrays, filter out the id and remove it when clicked

I am working with an object that contains multiple arrays and aiming to filter out the id of the item to be removed onClick. However, I have encountered an error while trying to implement this logic. The error message I received is filter is not a functio ...

JavaScript calculator not calculating values correctly

I am facing an issue with my JavaScript calculator. The problem occurs when I try to perform addition, such as adding 5+5, the result gets stuck at 10 and does not continue to increment (10, 15, 20, etc). Below is the code snippet that I am using: func ...

When combining Socket.io 1.0 with express 4.2, the outcome is a lack of socket connection

According to the title, I am attempting to integrate socket.io 1.0.4 with express 4.2, but all requests with "/?EIO" are resulting in a 404 error. Below are my file configurations: ./bin/www : #!/usr/bin/env node var debug = require('debug')(& ...

Having trouble changing fonts in JavaScript Photoshop using scripting on certain fonts

I have created a script for photoshop that is designed to change the font family to a different type. However, I am experiencing some inconsistencies in its performance. Here is the section of the script responsible for altering the font family: var origD ...

"Dealing with an array of routes in AngularJS $

Clicking on the Home link triggers the goTo function, but it redirects to a blank page as shown: https://i.sstatic.net/qerBI.png Upon clicking on the browser's back button, it redirects to the desired page (firstPage). https://i.sstatic.net/oaANp.p ...

Can you explain the distinction between using `yarn link` versus `npm link`?

There have been instances where npm link seemed to work better than yarn link which resulted in strange errors. This discrepancy caught my attention a few times. I was under the impression that both commands were essentially creating symbolic links, but ...

Tips for sending multiple commands in ngrx/effect (redux-observable)?

In my Angular 6 project, I am using ngrx/store to manage state. I have an effect that handles updating data and based on certain conditions, I need to dispatch different actions. What will be the impact of using switchMap instead of map in this scenario? ...

Unable to dynamically insert values into a JSON object

My goal is to populate a JSON object with objects that look like this: var books = [{ "no" : 1, "bookType":"fiction", "bookPrice": 60 },{ "no" : 2, "bookType":"f ...

mobile input sliders for selecting ranges

While working on a custom audio player, I encountered an issue with the default html5 input range object. Everything else seems to be working perfectly, with all events firing as needed, except for a frustrating problem on mobile Safari with iOS 11.4: Whe ...

Clear v-model without changing its associated values

I'm facing an issue with my <input> fields, which look like this: <input type="text" v-model=user.name" /> <input type="text" v-model="user.phone" /> <button @click="add">add user</button> Whenever the add user button i ...

Creating a dynamic list filter using JavaScript and three select boxes

Looking for a way to implement a similar feature to the one on this webpage: I will be showcasing a list of brands on the page, with each brand requiring three pieces of information: Starting letter Store (multiple options) Category (multiple options) ...

Performing the addition operation on two floating point numbers in JavaScript

The JavaScript code goes as follows: var receivedamt = parseFloat($('#cashRecText').val()).toFixed(2); console.log(receivedamt); var addon = parseFloat('5.00').toFixed(2); console.log(addon); addon = parseFloat(receivedamt).toFixed(2 ...

Move the divs within the overflow container by sliding them, then take out the initial element and append it to the end

Currently, when I utilize .appendTo(".wrapper") as shown in the code below, it eliminates the animation effect. My goal is to have the div on the far left slide out of view, triggering an overflow hidden effect, and then be placed at the end of the slide c ...

Could someone please explain how to obtain a compiled string within an AngularJS directive?

Check out the following code snippet for my custom directive: mymodule.directive("test", function($compile) { return { restrict: 'E', replace: true, template: '<div data-date="{{avail}}"></div>', ...