How to Integrate WebSockets with React Redux
Last Updated :
04 Apr, 2024
Integrating WebSockets with Redux allows for real-time bidirectional communication between the client (e.g. a web browser) and the server. This enables applications to push data from the server to the client instantly, facilitating features such as real-time updates, live notifications, and chat applications
Steps to Setup the Backend:
Step 1: Create a new directory for your project and navigate into it in your terminal.
mkdir server
cd server
Step2: Run the following command to initialize a new Node.js project and create a package.json file:
npm init -y
Step 3: Install web socket Dependencies from the given command.
npm install ws
The updated dependencies in package.json file will look like.
"dependencies": {
"ws": "^8.16.0"
}
Example: This example used to setup the backend for the project.
JavaScript
// index.js
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });
wss.on('connection', function connection(ws) {
ws.on('message', function incoming(message) {
console.log('Received:', message);
// Echo back the received message
ws.send(message);
});
});
Output: Run the server with the following command in the terminal
node index.js
Steps to Setup the Frontend
npx create-react-app foldername
Step 2: After creating your project folder i.e. foldername, move to it using the following command:
cd foldername
Step 3: Install required dependencies
npm install react-redux redux redux-thunk
Step 4: After setting up react environment on your system, we can start by creating an App.js file and create a directory by the name of components in which we will write our desired function.
Project Structure:

The updated dependencies in package.json file will look like.
"dependencies": {
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-redux": "^9.1.0",
"react-scripts": "5.0.1",
"redux": "^5.0.1",
"redux-thunk": "^3.1.0",
"web-vitals": "^2.1.4"
},
Approach to integrate WebSocket with React Redux:
- Configure Redux store with middleware like
redux-thunk
or redux-saga
for handling asynchronous actions, including WebSocket interactions. - Create a WebSocket instance for bidirectional real-time communication between the client and server.
- Create action creators for WebSocket events, such as sending messages to the server and handling incoming messages.
- Define reducers to update the Redux store based on WebSocket actions, ensuring state predictability and synchronization with server data.
- Dispatch WebSocket actions from components or middleware to initiate WebSocket communications and reflect real-time updates in the UI through Redux-managed state.
Example: Implementation to showcase the process integrating WebSockets with Redux using chat application.
JavaScript
//src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import { thunk } from 'redux-thunk';
import rootReducer from './reducers';
import App from './App';
import { connectWebSocket } from './actions/websocketActions';
const store = createStore(
rootReducer,
applyMiddleware(thunk)
);
store.dispatch(connectWebSocket());
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
JavaScript
// App.js
import React, { useEffect, useState } from 'react';
import { connect } from 'react-redux';
import {
connectWebSocket,
sendMessage,
receiveMessage
} from './actions/websocketActions';
const App = ({ connectWebSocket,
sendMessage, receiveMessage,
messages }) => {
const [messageText, setMessageText] = useState('');
useEffect(() => {
connectWebSocket();
}, [connectWebSocket]);
useEffect(() => {
const messageChannel =
new BroadcastChannel('chat_messages');
messageChannel.onmessage = (event) => {
// Update messages in this tab
// when a message is received from another tab
receiveMessage(event.data);
};
return () => {
messageChannel.close();
};
}, []);
const handleMessageChange = (e) => {
setMessageText(e.target.value);
};
const handleSubmit = (e) => {
e.preventDefault();
if (messageText.trim() !== '') {
sendMessage(messageText);
setMessageText('');
}
};
return (
<div className="App">
<h1>Real-Time Chat Application</h1>
<div className="chat-container">
{messages.map((message, index) => (
<div key={index} className="message">
{message}
</div>
))}
</div>
<form onSubmit={handleSubmit}>
<input
type="text"
value={messageText}
onChange={handleMessageChange}
placeholder="Type your message..."/>
<button type="submit">Send</button>
</form>
</div>
);
};
const mapStateToProps = (state) => ({
messages: state.websocket.messages
});
export default connect(mapStateToProps,
{
connectWebSocket,
sendMessage,
receiveMessage
})(App);
JavaScript
// websocketActions.js
let ws;
let messageChannel;
let isEventListenerSetup = false;
// Generate a unique identifier for each browser
const userId = Math.random().toString(36).substring(7);
export const connectWebSocket = () => (dispatch) => {
// Ensure WebSocket connection is established only once
if (!ws || ws.readyState === WebSocket.CLOSED) {
ws = new WebSocket('ws://localhost:8080');
ws.onopen = () => {
console.log('WebSocket connected successfully!');
};
ws.onmessage = async (event) => {
const message = await event.data.text();
const formattedMessage = `${userId}: ${message}`;
// Broadcast the received message
// to all Broadcast Channel clients
messageChannel.postMessage(formattedMessage);
};
ws.onerror = (error) => {
console.error('WebSocket error:', error);
};
ws.onclose = () => {
console.log('WebSocket connection closed.');
};
// Log the WebSocket object to check
// if it's being created multiple times
console.log('WebSocket:', ws);
}
if (!messageChannel) {
messageChannel = new BroadcastChannel('chat_messages');
}
if (!isEventListenerSetup) {
messageChannel.onmessage = (event) => {
};
isEventListenerSetup = true;
}
dispatch({
type: 'WEBSOCKET_CONNECTED',
payload: ws
});
};
export const sendMessage = (message) => (dispatch) => {
if (ws && ws.readyState === WebSocket.OPEN) {
ws.send(message);
}
};
export const receiveMessage = (message) => ({
type: 'WEBSOCKET_MESSAGE_RECEIVED',
payload: message
});
JavaScript
// WebSocketComponent.js
import React, { useEffect } from 'react';
import { connect } from 'react-redux';
import { connectWebSocket } from '../actions/websocketActions';
const WebSocketComponent = ({ connectWebSocket, messages }) => {
useEffect(() => {
const socket = connectWebSocket();
socket.onopen = () => {
console.log('WebSocket connected successfully!');
};
socket.onerror = (error) => {
console.error('WebSocket error:', error);
};
socket.onclose = () => {
console.log('WebSocket connection closed.');
};
return () => {
socket.close();
};
}, [connectWebSocket]);
return (
<div>
{messages.map((message, index) => {
console.log('Message:', message);
return (
<div
key={index}
style={{
padding: '5px 10px',
margin: '5px',
borderRadius: '5px',
alignSelf: message.source ===
'right' ? 'flex-end' : 'flex-start',
backgroundColor: message.source ===
'right' ? '#d3d3d3' : '#f0f0f0',
}}>
{message.content}
</div>
);
})}
</div>
);
};
const mapStateToProps = (state) => ({
messages: state.websocket.messages,
});
export default connect(mapStateToProps,
{ connectWebSocket })(WebSocketComponent);
JavaScript
//src/store/configureStore.js
import { createStore, applyMiddleware } from 'redux';
import { thunk } from 'redux-thunk';
import rootReducer from '../reducers';
const store = createStore(
rootReducer,
applyMiddleware(thunk)
);
export default store;
JavaScript
// reducers/websocketReducer.js
const initialState = {
connection: null,
messages: []
};
const websocketReducer = (state = initialState, action) => {
switch (action.type) {
case 'WEBSOCKET_CONNECTED':
return {
...state,
connection: action.payload
};
case 'WEBSOCKET_MESSAGE_RECEIVED':
return {
...state,
messages: [...state.messages, action.payload]
};
case 'WEBSOCKET_MESSAGE_SENT':
return {
...state,
messages: [...state.messages, `Sent: ${action.payload}`]
};
default:
return state;
}
};
export default websocketReducer;
JavaScript
// src/reducers/index.js
import { combineReducers } from 'redux';
import websocketReducer from './websocketReducer';
export default combineReducers({
websocket: websocketReducer
});
Steps to run the Application:
npm start
Output: Your project will be shown in the URL http://localhost:3000/

Similar Reads
How to Integrate Redux with React Components ?
Redux is an open-source JavaScript library for managing and centralizing application state. It helps you to write applications that behave consistently and are easy to test and run in different environments. It can also be understood as the predictable state container for the JavaScript app. It is m
4 min read
How to use React Context with React-Redux ?
React context with React-Redux is a popular state management library for React applications. Using React context with React-Redux is a powerful way to provide the Redux store to components deep within your component tree without manually passing it down through props. PrerequisitesNode.js and NPMRea
3 min read
How to Send WebSocket Requests with Postman ?
This article will show how to send WebSocket requests in Postman. Postman is a popular collaborative platform for API development. It offers different tools for designing, debugging, and testing an API, making it more efficient. WebSocket is an advanced technology used for real-time bidirectional co
3 min read
How to redirect in React with Typescript ?
Navigating users seamlessly through a React application is a fundamental aspect of creating a smooth and intuitive user experience. In this article, we delve into the world of redirects in React, specifically addressing the use of TypeScript for enhanced type safety and developer productivity.Prereq
2 min read
How to use Redux with ReactNative?
First, we create a fresh ReactNative Project by running the command ânpx react-native init reduxDemoâ. You can also integrate Redux into your existing project.Go to the project folder by âcd {rootDirectory}/reduxDemoâ and install dependencies.ânpm install reduxâ which is an official redux dependency
6 min read
Real-time Updates with WebSockets and React Hooks
The WebSocket protocol provides continuous, real-time, full-duplex communication between a client and server over a single TCP socket connection. The WebSocket protocol has only two plans: opening a handshake and facilitating data transfer. After the server receives the handshake request sent by the
5 min read
How to Test WebSocket APIs With Postman?
WebSocket is a communication protocol that provides full-duplex communication channels over a single, long-lived connection between clients and servers. Unlike HTTP, which is a request-response protocol, WebSocket allows both the client and server to send messages to each other independently at any
4 min read
Why we need Redux in React ?
Redux is a library used in JavaScript applications for managing application states. It is particularly used and more popular in terms of building single-page applications using frameworks like React. Redux can also be used with other frameworks or libraries as well. It serves as a centralized store
7 min read
Learn to use Websockets with Django
Django Channels is an extension of the Django framework that allows for handling WebSockets, HTTP2, and other protocols. It integrates with Djangoâs existing ORM and works seamlessly alongside Django views. In this tutorial, we will create a small Django project that displays "GeeksforGeeks" on the
3 min read
How to Create Store in React Redux ?
React Redux is a JavaScript library that is used to create and maintain state in React Applications efficiently. Here React Redux solves the problem by creating a redux store that stores the state and provides methods to use the state inside any component directly or to manipulate the state in a def
4 min read