Real-time features in React using WebSockets
Published: 2023-05-27 22:11:29

by [Esther Christopher](https://blog.openreplay.com/authors/esther-christopher)

<blockquote><em>Real-time features in web applications make it possible for users to be updated in the present moment of events by instigating communication between users and the server. They are important for improving the user's experience and providing them with actionable insights. This article will show you how to implement this feature in React by using WebSockets.</em></blockquote>


Why are real-time features important? 

* An instant and interactive experience for users.
*  Provides better customer support to users by using instant messaging to attend to questions or proffer solutions.
*   Keeps users updated to make informed decisions with the data and analytics provided.
* Makes users aware of newly added features to the app through push notifications.

[WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API) API is a technology that enables instant communication and data exchange between client and server. It is used to create real-time features such as chat applications, real-time collaboration tools, and live streaming.  

It is supported by most browsers, including Firefox, Chrome, and Safari, which makes it a widely adopted technology for creating real-time features in web applications. 

WebSockets libraries are available to be implemented in a [React](https://react.dev/) app to enable data exchange between client and server and create real-time features in an application. This is done by establishing a connection between the React app and the server using the WebSocket API.   


## Definition of WebSockets and how they differ from traditional HTTP requests

WebSockets is a communication protocol that enables real-time communication between a client and a server. It uses a standard WebSocket protocol that goes through TCP or IP to enable the connection between the client and the server.

WebSocket provides a persistent bi-directional communication channel between a client and a server. This means that data can be sent back and forth between the client and server without having to initiate a new connection each time to send a request. 

Unlike HTTP requests, each new request requires a response, after which it is terminated before a new request can be sent again. WebSockets work differently; it uses a stateful protocol. Once a connection is established, communication will continue until the connection is terminated by either the client or the server. 

## How WebSockets work and enable real-time communication

The WebSocket handshake system is similar to an HTTP system but has few differences. The client sends an HTTP request to the server with the "Upgrade" header specifying "WebSockets" to create a WebSocket connection. After the connection is established, data is sent back and forth between the client and server in real-time. Then either the client or server will initiate the "close" handshake to terminate the connection.

Due to this persistent connection, WebSockets are used to build real-time applications. It is a powerful technology for building engaging and interactive web applications.

## Different WebSocket libraries available for React

There are various libraries used with Websockets to manage WebSocket connections between the browser and server. They provide the features that enable WebSocket connections, like handling events and sending and receiving messages. 
To use these libraries, you must have installed `npm` and [Node.js](https://nodejs.org/en/docs) on your system and then `npm install` any of the libraries.

Some WebSockets libraries available with React are: 

*  [Socket.IO](https://socket.io/)
*  [SockJS](https://www.npmjs.com/package/sockjs)
*  [WS](https://www.npmjs.com/package/ws)
*  [React-use-websocket](https://www.npmjs.com/package/react-use-websocket)
*  [SockJS-client](https://www.npmjs.com/package/sockjs-client)
*  [uWebSockets.js](https://www.npmjs.com/package/uwsjs/v/1.0.0)

The specific library to use depends on your project and its use case. Some libraries, like Socket.IO and uWebSockets.js, provide more advanced real-time communication features, while others provide a simpler API. 

## A step-by-step guide to integrating WebSockets into a React app

Now let's see how to integrate WebSocket into a React app. For the sake of this tutorial, Socket.IO will be used to create real-time features in React. 

### Prerequisite
You should have [Node.js](https://nodejs.org/en/docs) installed on your local machine. 

### Integrating WebSockets into your React app
In your React app, install the Socket.IO library by typing in the following command in your terminal:
```
npm install socket.io-client
```
Next, you will create a WebSockets server using a Node.js HTTP server to manage the incoming connections.

Create a new file in your app and input the following code. Create a folder for the server and a `server.js` file. On your terminal, cd into the server folder and run `npm.io`. 

Input the following code in your `server.js` file. 
```javascript
const http = require("http");

const { Server } = require("socket.io");

const httpServer = http.createServer();

const PORT = 8080,
  HOST = "localhost";

const io = new Server(httpServer, {
  cors: {
    origin: "*", // or a list of origins you want to allow, e.g. ["http://localhost:3000"]
    credentials: true,
  },
});

io.on("connection", (socket) => {
  console.log(socket.id);
});

httpServer.listen(PORT, HOST, () => {
  console.log("Server running on port:", PORT);
});

```
This would create the WebSockets server listening on port 8080, which logs incoming client connections. It logs the socket ID to the console, which should be the same on the front end.

Now connect the WebSockets server to your React app. In your `App.js` file, add the following code:
```  javascript
import React, { useState, useEffect } from 'react';
import io from 'socket.io-client';

function App() {
  const [message, setMessage] = useState('');
  const [socket, setSocket] = useState(null);

  useEffect(() => {
    // connect to WebSocket server
    const newSocket = io("http://localhost:8080");
    setSocket(newSocket);

    newSocket.on('connect', () => {
      console.log('Connected to server', newSocket.id);
    });

      newSocket.on('disconnect', () => {
      console.log('Disconnected from server');

    });
  }, []);
}
  export default App;
```
This code creates a connection to the WebSockets server with the `io()` method from the Socket.IO library. It listens to connect and disconnect events with the event listeners. Once this is done, a connection has been created, and you can listen to events. `newSocket.id` should be the same as the `newSocket.id` created on the server side.

## Real-time features that can be created using WebSocket

Several real-time features can be created using WebSocket. Some examples of these features are:

* Chat applications: Chat applications allow users to communicate with each other instantly. Users can send messages, which are immediately sent to the server, and a response is sent back, all of which happens over the WebSocket connection. This allows for fast and efficient communication between users in real time.

* Live notification: This feature provides users immediate updates when new events occur. It notifies the users of certain developments. 

* Real-time data visualization: Real-time data visualization provides users with real-time information. An example is a dashboard that displays the performance of a company's website in real-time.

* Live streaming: This allows users to watch events, broadcasts, or other video content as it is happening in real-time.

<div style="background-color:#efefef; border-radius:8px; padding:10px; display:block;">
<hr/>
<h3><em>Session Replay for Developers</em></h3> 
<p><em>Uncover frustrations, understand bugs and fix slowdowns like never before with <strong><a href="https://github.com/openreplay/openreplay" target="_blank">OpenReplay</a></strong> — an open-source session replay suite for developers. It can be <strong>self-hosted</strong> in minutes, giving you complete control over your customer data.</em></p>
<img alt="OpenReplay" style="margin-top:5px; margin-bottom:5px;" width="768" height="400" src="https://raw.githubusercontent.com/openreplay/openreplay/main/static/openreplay-git-hero.svg" class="astro-UXNKDZ4E" loading="lazy" decoding="async">
<p><em>Happy debugging! <a href="https://openreplay.com" target="_blank">Try using OpenReplay today.</a></em><p>
<hr/>
</div>





## Implementing the chat application using WebSocket

After successfully installing WebSocket, creating the server, and connecting the WebSocket server from the React app, you will now implement the chat application feature using WebSocket.

To build the chat application, add the following code in your `server.js` file for the connection event listener:
```javascript
io.on("connection", (socket) => {
 console.log(socket.id);
 socket.on("message", (message) => {
   console.log(`Received message: ${message}`);
   socket.emit("message", message);
 });
});
```
This should go into your `ChatRoom` component, which you must have created.
```javascript
import React, { useState, useEffect } from "react";
import io from "socket.io-client";

const ChatRoom = () => {
  const [message, setMessage] = useState("");
  const [messages, setMessages] = useState([]);
  const [socket, setSocket] = useState(null);

  useEffect(() => {
    // connect to WebSocket server
    const newSocket = io("http://localhost:8080");
    setSocket(newSocket);

    // set up event listeners for incoming messages
    newSocket.on("connect", () => console.log("Connected to WebSocket"));
    newSocket.on("disconnect", () =>
      console.log("Disconnected from WebSocket")
    );
    newSocket.on("message", (data) => {
      setMessages((msgs) => [...msgs, data]);
    });

    // clean up on unmount
    return () => {
      newSocket.disconnect();
    };
  }, []);

  const handleSend = (e) => {
    e.preventDefault();
    if (message.trim() !== "") {
      // send message to WebSocket server
      socket.emit("message", message);
      setMessage("");
    }
  };

  return (
    <div>
      <h1>Chat Room</h1>
      <div>
        {messages.map((msg, index) => (
          <div key={index}>{msg}</div>
        ))}
      </div>
      <form onSubmit={handleSend}>
        <input
          type="text"
          value={message}
          onChange={(e) => setMessage(e.target.value)}
        />
        <button type="submit">Send</button>
      </form>
    </div>
  );
};
export default ChatRoom;
```
This code sets up a WebSocket connection to a server running on `http://localhost:8080`. It uses the useState hook to manage the state of the chat messages and the current message being typed. The [useEffect](https://legacy.reactjs.org/docs/hooks-effect.html) hook is used to set up the WebSocket connection and event listeners for incoming messages. When the user types a new message and clicks the send button, the `handleSend` function sends the message to the WebSocket server using the emit method. The incoming messages are added to the messages array in the component's state, which is then displayed in the chat interface.

You should see something like this: 

![-](https://blog.openreplay.com/images/real-time-features-in-react-using-websockets/images/bszYVV7.jpg)

And also:

![-](https://blog.openreplay.com/images/real-time-features-in-react-using-websockets/images/y388wNV.jpg)


The second example of implementing a real-time feature using WebSocket will be live notification. 

For the server side, you also need to emit the notification event to send notifications to all connected clients. The following code gives an example: 
```javascript
io.on("connection", (socket) => {
  console.log(socket.id);
  socket.on("message", (message) => {
    console.log(`Received message: ${message}`);
    io.emit("notification", message);
  });
});
```
This should go into a component for the live notification:  
```javascript
import React, { useState, useEffect } from "react";
import io from "socket.io-client";

const socket = io("http://localhost:8080");
function App() {
  const [notifications, setNotifications] = useState([]);

  useEffect(() => {
    // Listen for incoming notifications from the server
    socket.on("notification", (notification) => {
      setNotifications([...notifications, notification]);
    });

    // Clean up event listeners on unmount
    return () => {
      socket.off("notification");
    };
  }, [notifications]);

  return (
    <div>
      <h1>Live Notifications</h1>
      <ul>
        {notifications.map((notification, index) => (
          <li key={index}>{notification}</li>
        ))}
      </ul>
    </div>
  );
}

export default App;
```
The useEffect hook sets up a listener for incoming notifications from the server. When a new notification is received, the notification state gets updated with the new notification. The user interface then gets updated to show the notification to the user.

This code listens for incoming message events from clients. When a new message is received, the message is broadcast to all connected clients by emitting the notification event to each client. This sends the notification message to all connected clients, including the React app we created earlier.


## Best Practices for Using WebSockets in a React App

Consider a few best practices for using WebSockets in a React app.

* Use efficient data formats: Employ the use of efficient data formats such as [JSON](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/JSON) when sending data over a WebSocket connection for improved performance. 

* Manage WebSocket connections: WebSocket connections should be properly maintained to ensure performance and reliability. It is advisable to create and maintain one WebSocket connection for the duration of your app. 

* Use a WebSocket library: Use a WebSocket library such as Socket.IO or SockJS for the features they provide instead of implementing WebSocket functionality from scratch.

* Test in detail: Finally, make sure to test your WebSocket implementation in detail for performance and reliability.


## Conclusion

In this article, you learned about WebSockets, their role in creating real-time features in applications, and how they differ from traditional HTTP requests. Then you went ahead to create a WebSocket server and connect it to your React app before finally implementing some real-time features in the application. 

You can play around and explore with WebSockets and implement other real-time features to further deepen your understanding. For further reading on  [WebSocket](https://websockets.readthedocs.io/en/stable/) and [Socket.IO](https://socket.io/) libraries.  
The source code for implementing the live features is available on my [GitHub repository](https://github.com/EstherChristopher/WebSocket-Chat-App/tree/Chat-application).