1. Introduction
WebSocket is a protocol that implements two-way communication in web applications. It allows the server to actively push data to the client without requiring the client to initiate a request. In modern real-time applications, WebSocket is often used in scenarios such as real-time data transmission, chat functions, real-time notifications and multi-person collaboration. In this blog, we will explore how to use WebSocket to enable real-time communication in React 18 applications.
2. Preparation
Before we start, we need to install React 18 and make sure you have the basics of React Hooks. In addition, we will also use WebSocket's npm package to implement WebSocket connections. You can install it using npm or yarn via the following command:
npm install websocket # oryarn add websocket
3. Write custom hooks
import { useEffect, useRef, useState } from 'react'; import WebSocketClient from 'websocket'; export function useWebSocket(accessToken: string, requestName: string): SocketType { const clientRef = useRef<WebSocketClient | null>(null); const [isActive, setIsActive] = useState<boolean>(false); const [socketClient, setSockClient] = useState<WebSocketClient | null>(null); // Get url let port = ; let wsUrl = ''; if ( === 'https:') { //If it is currently HTTPS encrypted, then use wss if (!port) { port = '4174'; } wsUrl = 'wss:'; } else { if (!port) { port = '8080'; } wsUrl = 'ws:'; } wsUrl += `//${}:${port}/api/ws/plugins/${requestName}?token=` + accessToken; if (!socketClient) { setSockClient(new WebSocketClient(wsUrl, isActive)); // Create a WebSocketClient instance and pass in the URL and active status isActive } useEffect(() => { = socketClient; if (!socketClient?.socket) { socketClient?.start(); // Start WebSocket connection } return () => { socketClient?.close(); // Close WebSocket connection when component uninstallation }; }, []); // Create a WebSocket connection const connect = () => { const client = ; if (client) { (); // Establish a WebSocket connection } }; // Close WebSocket connection const close = () => { const client = ; if (client) { (); // Close WebSocket connection } }; // Subscribe to message handler const subscribe = (handler: MessageHandler) => { const client = ; setIsActive(true); if (client) { (handler); } }; // Unsubscribe to the message const unsubscribe = () => { const client = ; if (client && isActive) { setIsActive(false); (); } }; // Send a message const send = (message: string) => { const client = ; if (client && ?.readyState === ) { (message); // Send a message } else if (client && ?.readyState === ) { // The WebSocket connection is not established or has been closed, and the connection needs to be re-established (); // Establish a WebSocket connection } }; return { connect, close, subscribe, unsubscribe, send }; }
In the above code, we use useRef to save the WebSocketClient instance and use useState to manage isActive and socketClient states. By creating the URL and accessToken of the WebSocket connection, we can instantiate the WebSocketClient in the useEffect hook. Then use the useEffect hook to start and close the WebSocket connection and close the connection when the component is uninstalled.
4. Create a WebSocketProvider
In order to share the WebSocket connection object throughout the application, we need to create a WebSocketProvider component. This component will use the provider pattern to provide the connection object to the child component.
Create a file named in your project and add the following code:
import React, { useContext, useEffect } from 'react'; import { useWebSocket } from './useWebSocket'; const WebSocketContext = (); export const useWebSocketContext = () => { return useContext(WebSocketContext); }; export const WebSocketProvider = ({ children, accessToken }) => { const webSocket = useWebSocket(accessToken); useEffect(() => { (); return () => { (); }; }, [webSocket]); return ( < value={webSocket}> {children} </> ); };
In the above code, we use the useWebSocket hook to get the WebSocket connection object, and connect the WebSocket in the useEffect hook, and close the connection when the component is uninstalled. We then provide the connection object to the child component, by creating one.
5. Use shared connections in components
Now we can use the shared WebSocket connection in any component of the application.
Suppose we have a component called ChatComponent which requires a WebSocket connection to implement the live chat function. In the file, add the following code:
import React from 'react'; import { useWebSocketContext } from './WebSocketProvider'; function ChatComponent() { const webSocket = useWebSocketContext(); const sendMessage = () => { if (webSocket) { ('Hello, WebSocket!'); } }; return ( <div> <button onClick={sendMessage}>Send Message</button> </div> ); } export default ChatComponent;
In the above code, we use useWebSocketContext to get the WebSocket connection object. We can then call the send method in the component to send the message.
6. Sample application: Live chat
We use the above code to create a live chat application as an example. In your project, create a folder called RealTimeChatApp and then create the following file in the folder:
- `:` Main application component
- `:` Live Chat Component
- ``: `WebSocket` connection provider
In, add the following code:
import React from 'react'; import ChatComponent from './ChatComponent'; import { WebSocketProvider } from './WebSocketProvider'; function RealTimeChatApp() { const accessToken = 'your_access_token'; // Replace with your access token return ( <WebSocketProvider accessToken={accessToken}> <div> <h1>Real Time Chat App</h1> <ChatComponent /> </div> </WebSocketProvider> ); } export default RealTimeChatApp;
Then, in, add the following code:
import React from 'react'; import { useWebSocketContext } from './WebSocketProvider'; function ChatComponent() { const webSocket = useWebSocketContext(); const [messages, setMessages] = ([]); const [newMessage, setNewMessage] = (''); (() => { const messageHandler = (message) => { setMessages((prevMessages) => [...prevMessages, message]); }; (messageHandler); return () => { (); }; }, [webSocket]); const sendMessage = () => { if (webSocket) { (newMessage); setNewMessage(''); } }; return ( <div> <div> {((message, index) => ( <div key={index}>{message}</div> ))} </div> <div> <input type="text" value={newMessage} onChange={(e) => setNewMessage()} /> <button onClick={sendMessage}>Send</button> </div> </div> ); } export default ChatComponent;
Finally, launch your app, access the RealTimeChatApp component, and you can view the live chat function in your browser.
7. Summary
This article describes how to use WebSocket for real-time communication in React 18 applications and shows how to share WebSocket connection objects through custom hooks and provider patterns. In this way, we can use the same connection object in multiple components, thus avoiding unnecessary connection duplication instantiation and performance overhead. WebSocket plays an important role in modern real-time applications, helping us achieve more efficient communication and user experience.
Hopefully this article helps you understand how to use WebSocket in React 18 and achieve the goal of sharing connections in your application. If you want to further explore the advanced usage of WebSocket, you can dig into the various options and features of WebSocket to meet your actual needs.
The above is the detailed explanation of the real-time communication function using React18 and WebSocket. For more information on building real-time communication with React18 WebSocket, please follow my other related articles!