• Articles
  • Tutorials
  • Interview Questions

The Guide to React WebSockets

The Guide to React WebSockets
Tutorial Playlist

In this blog, we’ll explore React WebSocket. We’ll look at how web technologies evolved, culminating with the emergence of WebSockets, a vastly superior improvement on HTTP for building real-time web apps. We’ll learn about its concepts, components, implementation, and real-time features. 

What is React WebSocket?

React WebSocket refers to the integration of WebSockets within a React application, it is not a specific technology or library itself. Let’s break down what each of these terms means:

  1. React: React is a popular JavaScript library for building user interfaces. It’s maintained by Facebook and a community of developers. React allows you to create reusable UI components and manage the state of your application efficiently.
  2. WebSocket: A very remarkable feature of the WebSocket communication protocol is the ability to have full-duplex, bidirectional communication channels all wrapped up neatly within a single TCP connection. It enables real-time communication between a client (usually a web browser) and a server. Unlike traditional HTTP requests, WebSocket allows data to be pushed from the server to the client and from the client to the server without the need for the client to poll the server for updates constantly.

When discussing “React WebSocket,” you’re likely referring to integrating WebSocket functionality into a React application. This allows your React app to establish WebSocket connections with a server, enabling real-time data transfer and updates. You can use libraries or packages like socket.io-client or the WebSocket API built into browsers to achieve this integration.

Components of WebSocket in React

When integrating WebSocket functionality into a React application, you’ll typically work with several components to establish and manage WebSocket connections. Here are the key components you’ll encounter:

  1. WebSocket Connection: This is the core component responsible for establishing a WebSocket connection to a server. You can use the `WebSocket` API provided by browsers or a WebSocket library like `socket.io-client` in React to create and manage this connection. Typically, you’ll create an instance of the WebSocket connection and specify the WebSocket server’s URL as a parameter.
  2. Event Listeners: Event listeners are used to handle various WebSocket events. You should set up listeners for events such as
    1.    ‘open’: Triggered when the WebSocket connection is successfully established.
    2.    ‘message’: Fired when a message is received from the server. This is where you handle incoming data.
    3.    ‘close’: Called when the WebSocket connection is closed, either by the server or due to an error.
    4.    ‘error’: Invoked when an error occurs in the WebSocket connection.
  3. Sending Data: To send data to the WebSocket server, you can use the `send()` method provided by the WebSocket connection. This allows you to transmit messages or data to the server for processing.
  4. React State: In a React application, you’ll often use React state to manage and display WebSocket data within your components. When you receive data from the WebSocket server, you can update the state of your React component, triggering re-renders to display the new data in your UI.
  5. Component Lifecycle: Managing the WebSocket connection’s lifecycle is crucial. You should open the connection when your React component mounts and close it when the component unmounts to prevent memory leaks. Typically, this is done in the `componentDidMount` and `componentWillUnmount` lifecycle methods (for class components) or in the `useEffect` hook (for functional components).
  6. Error Handling: WebSocket connections can encounter errors, such as network issues or problems with the server. Implement error-handling logic to gracefully handle these situations. You can display error messages or attempt to reconnect the WebSocket as needed.

Here’s a simplified example of how these components might come together in a React component:

  javascript

import React, { Component } from 'react';
class WebSocketComponent extends Component {
  constructor() {
    super();
    this.state = {
      messages: [],
    };
    this.websocket = new WebSocket('wss://example.com'); // WebSocket URL
  }
  componentDidMount() {
    this.websocket.addEventListener('open', () => {
      console.log('WebSocket connection established');
    });
    this.websocket.addEventListener('message', (event) => {
      const message = JSON.parse(event.data);
      // Update state to display the received message
      this.setState((prevState) => ({
        messages: [...prevState.messages, message],
      }));
    });
    this.websocket.addEventListener('close', () => {
      console.log('WebSocket connection closed');
      // You can implement reconnection logic here if needed
    });
    this.websocket.addEventListener('error', (error) => {
      console.error('WebSocket error:', error);
      // Handle WebSocket errors here
    });
  }
  componentWillUnmount() {
    // Close the WebSocket connection when the component unmounts
    this.websocket.close();
  }
  sendMessage(message) {
    // Send a message to the WebSocket server
    this.websocket.send(JSON.stringify(message));
  }
  render() {
    // Render UI using this.state.messages
  }
}
export default WebSocketComponent;

This example demonstrates a simple React component that establishes a WebSocket connection, handles incoming messages, and updates the component’s state to display those messages in the UI. It also handles the lifecycle and error aspects of WebSocket integration in React.

WebSocket Vs. Traditional HTTP

WebSocket and traditional HTTP are two types of web communication protocols with unique features for specific purposes. Here’s a comparison of some key features of WebSocket and HTTP:

FeatureWebSocketHTTP
Communication typeBidirectionalHalf-duplex
LatencyLowHigher
Bandwidth usageLessMore
Ideal forReal-time applications, such as chat, gaming, and live updatesServing static and dynamic content

Get 100% Hike!

Master Most in Demand Skills Now !

How to Use React WebSocket

To use WebSocket in a React application, you’ll need to follow these steps:

  1. Set Up Your React Project:

If you don’t already have a React project, create one using a tool like Create React App:

npx create-react-app my-websocket-app
 cd my-websocket-app
  1. Install WebSocket Library:

Choose a WebSocket library to use. A common choice is `socket.io-client` for its ease of use and compatibility with both the client and server sides. Install it via npm or yarn:

npm install socket.io-client
     # or
yarn add socket.io-client
  1. Create a WebSocket Component:

Create a new React component where you will handle WebSocket functionality. You can name it something like `WebSocketComponent.js`.

  1. Import the WebSocket Library:

Import the WebSocket library at the top of your component file:

import { io } from 'socket.io-client';
  1. Initialize WebSocket Connection:

Set up the WebSocket connection by creating a connection instance. Replace `’http://example.com‘` with the URL of your WebSocket server:

const socket = io('http://example.com');
  1. Handle WebSocket Events:

Add event listeners to handle various WebSocket events, such as ‘connect,’ ‘message,’ ‘disconnect,’ and ‘error.’ For example:

     socket.on('connect', () => {
       console.log('WebSocket connected');
     });
     socket.on('message', (data) => {
       console.log('Received message:', data);
       // Handle the received data
     });
     socket.on('disconnect', () => {
       console.log('WebSocket disconnected');
     });
     socket.on('error', (error) => {
       console.error('WebSocket error:', error);
       // Handle WebSocket errors
     });

Send Data Over WebSocket:

  1. Send Data Over WebSocket:

You can send data to the WebSocket server using the `socket.emit()` method. For example:

     socket.emit('chatMessage', { text: 'Hello, server!' });
  1. Clean Up WebSocket Connection:

To prevent memory leaks, make sure to close the WebSocket connection when your component unmounts. You can do this using a cleanup function:

javascript

     useEffect(() => {
       return () => {
         socket.disconnect();
       };
     }, []);
  1. Render UI:

Finally, render your React component and display the data you receive from the WebSocket server as needed.

Here’s a basic example of a React component that establishes a WebSocket connection:

javascript

import React, { useEffect } from 'react';
import { io } from 'socket.io-client';
const WebSocketComponent = () => {
  const socket = io('http://example.com');
  useEffect(() => {
    socket.on('connect', () => {
      console.log('WebSocket connected');
    });
    socket.on('message', (data) => {
      console.log('Received message:', data);
      // Handle the received data in your application
    });
    return () => {
      socket.disconnect();
    };
  }, []);
  return (
    <div>
      {/* Render your UI here */}
    </div>
  );
};
export default WebSocketComponent;

This component establishes a WebSocket connection, handles basic events, and disconnects when the component is unmounted. You can expand on this foundation to build real-time features into your React application.

How to Get Data from React WebSocket

The below given process describes how to get data from React WebSocket:

Getting Started

npm install react-use-websocket
import useWebSocket from 'react-use-websocket';
// Define the WebSocket URL you want to connect to
const socketUrl = 'wss://echo.websocket.org';
// Initialize the WebSocket connection using react-use-websocket
const {
  sendMessage,
  sendJsonMessage,
  lastMessage,
  lastJsonMessage,
  readyState,
  getWebSocket,
} = useWebSocket(socketUrl, {
  onOpen: () => console.log('WebSocket opened'),
  shouldReconnect: (closeEvent) => true,
});
// Now you can use these variables and functions in your component.

Interface

type UseWebSocket<T = unknown> = (
  // Url can be a string or a memoized async function that returns a string.
  url: string | () => Promise<string>,
  options: {
    fromSocketIO?: boolean; // Whether to use the Socket.IO protocol
    queryParams?: { [field: string]: any }; // Optional query parameters for the WebSocket URL
    protocols?: string | string[]; // WebSocket protocols to use
    share?: boolean; // Whether to share the WebSocket connection
    onOpen?: (event: WebSocketEventMap['open']) => void; // Callback for when the WebSocket connection is opened
    onClose?: (event: WebSocketEventMap['close']) => void; // Callback for when the WebSocket connection is closed
    onMessage?: (event: WebSocketEventMap['message']) => void; // Callback for when a message is received
    onError?: (event: WebSocketEventMap['error']) => void; // Callback for WebSocket errors
    onReconnectStop?: (numAttempts: number) => void; // Callback when reconnection attempts are stopped
    shouldReconnect?: (event: WebSocketEventMap['close']) => boolean; // Function to determine whether to reconnect
    reconnectInterval?: number | ((lastAttemptNumber: number) => number); // Interval for reconnection
    reconnectAttempts?: number; // Maximum number of reconnection attempts
    filter?: (message: WebSocketEventMap['message']) => boolean; // Function to filter incoming messages
    retryOnError?: boolean; // Whether to retry on WebSocket errors
    eventSourceOptions?: EventSourceInit; // Options for EventSource (if used)
  } = {},
  shouldConnect: boolean = true,
) => {
  // Methods and properties returned by the function
  sendMessage: (message: string, keep: boolean = true) => void; // Send a text message
  sendJsonMessage: (jsonMessage: T, keep: boolean = true) => void; // Send a JSON message
  lastMessage: WebSocketEventMap['message'] | null; // Last received message
  lastJsonMessage: T | null; // Last received JSON message
  readyState: number; // WebSocket ready state (0, 1, 2, 3)
  getWebSocket: () => (WebSocketLike | null); // Get the WebSocket object (if using shared connection)
}

Requirements

You can only utilize it in a functional component supporting React Hooks, not in a class component. This is applicable to React versions 16.8 and newer.

async urls

Instead of providing a static string as the initial argument for useWebSocket, you have the option to supply a function that yields a string or a promise that resolves to a string. Nevertheless, it’s essential to keep in mind that the usual rules still apply. Specifically, if the function reference undergoes any changes, it will trigger the function again. This could result in the creation of a new WebSocket instance if the URL returned by the function has changed.

import useWebSocket from 'react-use-websocket';
// In a functional React component
const getSocketUrl = useCallback(() => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve('wss://echo.websocket.org');
    }, 2000);
  });
}, []);
const { sendMessage, lastMessage, readyState, getWebSocket } = useWebSocket(
  getSocketUrl,
  STATIC_OPTIONS // Your static options here
);

API

sendMessage
type sendMessage = (message: string, keep: boolean = true) => void;

The parameter you provide to `sendMessage` will be forwarded directly to the WebSocket’s `send` method. `sendMessage` remains constant and can be handed down to child components without causing changes to its props. Messages sent before the WebSocket connection is established will be stored in a queue and sent once the connection is active. If you want to send a message immediately without queuing, you can make use of the ‘keep’ parameter.

sendJsonMessage
type sendJsonMessage = (message: any, keep: boolean = true) => void;

The message will initially undergo the process of being converted into a JSON string using `JSON.stringify`.

lastMessage
type lastMessage = WebSocketEventMap['message'];
It will be a raw MessageEvent received from the WebSocket without any parsing.
lastJsonMessage
type lastMessage = any;
`lastJsonMessage` will represent a JavaScript object that has been parsed from `lastMessage`. If `lastMessage` does not contain a valid JSON string, `lastJsonMessage` will be an empty object.
readyState
enum ReadyState {
  UNINSTANTIATED = -1,
  CONNECTING = 0,
  OPEN = 1,
  CLOSING = 2,
  CLOSED = 3,
}

It will be a numerical value indicating the WebSocket’s readiness state. An integer value of -1 doesn’t correspond to a valid WebSocket readiness state; instead, it signifies that the WebSocket hasn’t been created yet. This can occur when the URL is null or when the connect parameter is set to false.

getWebSocket
type getWebSocket = () => WebSocketLike | Proxy<WebSocketLike>;

If the WebSocket is being shared, invoking this function will create a Proxy instance only when needed, wrapping the underlying WebSocket. You can access and modify properties on the returned value, which will directly affect the WebSocket. However, specific properties and methods are safeguarded and cannot be modified or invoked. The functions close and send are included, along with event handlers onmessage, onclose, onopen, and onerror.  An example of using this:

const { sendMessage, lastMessage, readyState, getWebSocket } = useWebSocket(
  'wss://echo.websocket.org',
  { share: true }
);
useEffect(() => {
  console.log(getWebSocket().binaryType);
  // Output: 'blob'
  // Changing the binaryType property of WebSocket
  getWebSocket().binaryType = 'arraybuffer';
  console.log(getWebSocket().binaryType);
  // Output: 'arraybuffer'
  // Attempting to change the event handler
  getWebSocket().onmessage = console.log;
  // A warning is logged to the console: 'The WebSocket's event handlers should be defined through the options object passed into useWebSocket.'
  // Attempting to change an immutable property
  getWebSocket().url = 'www.google.com';
  console.log(getWebSocket().url);
  // Output: 'wss://echo.websocket.org'
  // Attempting to call webSocket#send
  getWebSocket().send('Hello from WebSocket');
  // No message is sent, and no error is thrown (a no-op function was returned), but an error will be logged to the console: 'Calling methods directly on the WebSocket is not supported at this moment. You must use the methods returned by useWebSocket.'
}, []);

When the WebSocket is not shared, as determined by the options, the return value corresponds directly to the underlying WebSocket. Consequently, you can access and utilize methods like close and send on it.

Reconnecting

By default, useWebSocket doesn’t make automatic reconnection attempts to a WebSocket. However, you can modify this behavior using specific options. To enable reconnection attempts upon encountering errors, set the retryOnError option to true.

Dealing with CloseEvents can be less straightforward, as it may not be immediately clear whether the closure was initiated intentionally by the client or due to unexpected server restarts. To handle this, you should provide a callback function, shouldReconnect as an option. This callback takes the WebSocket’s CloseEvent as its only argument and should return either true or false. If it returns true, useWebSocket will make reconnection attempts, with a default maximum of 20 attempts and a default interval of 5000 milliseconds.

Here’s an example to illustrate:

import { useEffect, useRef } from 'react';
import useWebSocket from 'react-use-websocket';
// Create a ref to track component unmounting
const didUnmount = useRef(false);
// Establish a WebSocket connection with specified options
const [sendMessage, lastMessage, readyState] = useWebSocket(
  'wss://echo.websocket.org',
  {
    // Customize reconnection behavior
    shouldReconnect: (closeEvent) => {
      /*
      Example scenario: useWebSocket will handle unmounting for you, 
      but in this case, we want to prevent automatic reconnection.
      */
      return didUnmount.current === false;
    },
    reconnectAttempts: 10,        // Maximum reconnection attempts
    reconnectInterval: 3000,     // Interval between reconnection attempts in milliseconds
  }
);
// Use an effect to update the 'didUnmount' ref on component unmount
useEffect(() => {
  return () => {
    didUnmount.current = true; // Component is unmounting, set the flag to true
  };
}, []);
// Now you can use 'sendMessage', 'lastMessage', and 'readyState' in your component.

Alternatively, you have the option to supply a function for `Options#reconnectInterval`. This function takes the nth last reconnection attempt as a parameter and should return a numerical value representing the duration of the next interval. This approach provides greater flexibility for implementing more advanced reconnection strategies, such as Exponential Backoff.

import useWebSocket from 'react-use-websocket';
// Establish a WebSocket connection with custom reconnection settings
const [sendMessage, lastMessage, readyState] = useWebSocket(
  'wss://echo.websocket.org',
  {
    // Always attempt to reconnect on close events
    shouldReconnect: (closeEvent) => true,
    reconnectAttempts: 10,
    /*
    Define the reconnectInterval as a function that calculates the reconnection
    interval based on the attempt number. The equation results in a reconnect pattern
    of 1 second, 2 seconds, 4 seconds, 8 seconds, and then caps at 10 seconds until
    the maximum number of attempts (10) is reached.
    */
    reconnectInterval: (attemptNumber) =>
      Math.min(Math.pow(2, attemptNumber) * 1000, 10000),
  }
);
// You can now use 'sendMessage', 'lastMessage', and 'readyState' in your component.

Features of React Websocket

React WebSocket libraries simplify the integration of WebSocket functionality into React applications, providing hooks, event handlers, and configuration options to manage real-time communication with ease. These features empower developers to create responsive and interactive applications that rely on WebSocket technology. The key features associated with using WebSocket in React applications include:

  1. Real-Time Communication: WebSocket allows real-time bidirectional communication between a client (React app) and a server. It’s well-suited for applications that require instant updates, such as chat applications, online gaming, and collaborative tools.
  2. Integration with React: React WebSocket integration typically involves using packages like react-use-websocket or similar libraries. These packages provide hooks and utilities to easily incorporate WebSocket functionality into React components, making it convenient to manage WebSocket connections and data updates within React’s component-based architecture.
  3. Hooks for WebSocket Management: React WebSocket libraries offer custom hooks, such as useWebSocket, which simplify the process of establishing WebSocket connections, sending and receiving messages, and managing the connection’s lifecycle. These hooks make it easy to integrate WebSocket functionality into functional components.
  4. Reconnection Strategies: Many React WebSocket libraries allow you to define custom reconnection strategies. You can specify rules for when and how to attempt reconnecting to the WebSocket server if the connection is lost, providing flexibility for handling connection failures.

Real-time Features that can be Created Using WebSocket

Some of the real-time features that can be created using WebSocket are described below:

  1. Live Chat Applications: Build real-time chat applications where messages appear instantly as users type.
  2. Collaborative Whiteboards: Create collaborative whiteboard apps where multiple users can draw simultaneously in real-time.
  3. Gaming: Develop online multiplayer games with synchronized gameplay and real-time updates.
  4. Stock Market Updates: Display live stock market data with instant updates to keep traders informed.
  5. Live Notifications: Send real-time notifications to users for events like new emails or social media interactions.

Conclusion

React WebSocket is a strong tool that helps developers make dynamic web apps in real-time. The client and server can talk back and forth, making the user experience more fun and interactive. To improve your web development projects, learn about React WebSocket and compare it to HTTP. Thus, use it effectively.

Remember React WebSocket when you start a web development project that needs real-time interaction. Embrace the future of web development. Let your applications thrive in real-time communication.

FAQ’s

1. Why we use websockets in react native?

WebSockets are used in React Native to enable real-time, bidirectional communication between a mobile app and a server. This is useful for building apps like chat, games, and other interactive features.

2. How to check if websocket is open react native.

To check if a WebSocket is open in React Native, you can use the following:

const isOpen = socket.readyState === WebSocket.OPEN;

This will return true if the WebSocket is open, and false otherwise.

3. How to get data from WebSocket React.

To get data from a WebSocket in React, you can use the following:

const data = event.data;

This will return the data that was received in the WebSocket message.

Course Schedule

Name Date Details
Web Development Courses 25 May 2024(Sat-Sun) Weekend Batch
View Details
Web Development Courses 01 Jun 2024(Sat-Sun) Weekend Batch
View Details
Web Development Courses 08 Jun 2024(Sat-Sun) Weekend Batch
View Details