React WebSocket Hook
react-use-websocket is a React Hook designed to simplify and robustly integrate WebSocket communication into React components. It provides a straightforward API for managing WebSocket connections, sending messages, and reacting to incoming data and connection state changes. The current stable version is 4.13.0, which has a peer dependency on React 18. For applications still using React 17, version 3.0.0 is recommended. The library focuses on ease of use, offering features like automatic JSON serialization/deserialization for messages, memoized `sendMessage` callbacks, and options for sharing a single WebSocket connection across multiple components. Its release cadence is moderate, with significant breaking changes typically aligned with major React versions or substantial API overhauls. A key differentiator is its robust handling of connection failures and an explicit API for managing the connection lifecycle, alongside experimental Socket.IO support.
Common errors
-
TypeError: useWebSocket is not a function
cause Incorrect import statement (e.g., default import instead of named) or trying to use CommonJS `require` in an ESM context.fixEnsure you are using `import { useWebSocket } from 'react-use-websocket';` and your project is configured for ESM if applicable. -
Error: Invalid hook call. Hooks can only be called inside of the body of a function component.
cause The `useWebSocket` hook is being called outside of a React function component or a custom hook.fixEnsure `useWebSocket` is only invoked directly within the body of a React function component or another custom hook. -
WebSocket connection failed: wss://demos.kaazing.com/echo
cause The `demos.kaazing.com/echo` server is frequently offline or unreachable, causing connection attempts to fail.fixChange the `socketUrl` to a more reliable endpoint like `wss://echo.websocket.org` for testing, or use a trusted production WebSocket server.
Warnings
- breaking Version 4.0.0 and above of `react-use-websocket` now depends on React 18. If your project is still on React 17 or older, you must install version 3.0.0.
- breaking In version 2.0.0, the return value of the `useWebSocket` hook changed from an array to an object. Destructuring must be updated accordingly.
- gotcha The `wss://demos.kaazing.com/echo` endpoint, often used in examples, has been intermittently unavailable. Relying on it for production or critical testing is not advised as it will lead to connection failures.
- gotcha To explicitly close or unsubscribe a component from a WebSocket connection, passing `false` as the third parameter to `useWebSocket` is the recommended method since v2.0.0. While setting `socketUrl` to `null` still works, it's less explicit.
Install
-
npm install react-use-websocket -
yarn add react-use-websocket -
pnpm add react-use-websocket
Imports
- useWebSocket
import useWebSocket from 'react-use-websocket'; const useWebSocket = require('react-use-websocket');import { useWebSocket } from 'react-use-websocket'; - ReadyState
import ReadyState from 'react-use-websocket';
import { ReadyState } from 'react-use-websocket'; - Options
import { Options } from 'react-use-websocket';import type { Options } from 'react-use-websocket';
Quickstart
import React, { useState, useCallback, useEffect } from 'react';
import useWebSocket, { ReadyState } from 'react-use-websocket';
export const WebSocketDemo = () => {
// Public API that will echo messages sent to it back to the client
const [socketUrl, setSocketUrl] = useState('wss://echo.websocket.org');
const [messageHistory, setMessageHistory] = useState([]);
const { sendMessage, lastMessage, readyState } = useWebSocket(socketUrl);
useEffect(() => {
if (lastMessage !== null) {
setMessageHistory((prev) => prev.concat(lastMessage.data));
}
}, [lastMessage]);
const handleClickChangeSocketUrl = useCallback(
() => setSocketUrl('wss://demos.kaazing.com/echo'),
[]
);
const handleClickSendMessage = useCallback(() => sendMessage('Hello'), []);
const connectionStatus = {
[ReadyState.CONNECTING]: 'Connecting',
[ReadyState.OPEN]: 'Open',
[ReadyState.CLOSING]: 'Closing',
[ReadyState.CLOSED]: 'Closed',
[ReadyState.UNINSTANTIATED]: 'Uninstantiated',
}[readyState];
return (
<div>
<button onClick={handleClickChangeSocketUrl}>
Click Me to change Socket Url
</button>
<button
onClick={handleClickSendMessage}
disabled={readyState !== ReadyState.OPEN}
>
Click Me to send 'Hello'
</button>
<span>The WebSocket is currently {connectionStatus}</span>
{lastMessage ? <span>Last message: {lastMessage.data}</span> : null}
<h3>Message History:</h3>
<ul>
{messageHistory.map((message, idx) => (
<li key={idx}>{message}</li>
))}
</ul>
</div>
);
};