基于React通用的 WebSocket 钩子 useWebSocket
useWebSocket
钩子封装:
import { useEffect, useRef, useState, useCallback } from 'react';
const useWebSocket = (url: string) => {
const wsRef = useRef<WebSocket | null>(null); // 用来存储 WebSocket 实例
const [isConnected, setIsConnected] = useState(false);
const [lastMessage, setLastMessage] = useState<string | null>(null);
const [error, setError] = useState<string | null>(null);
// 初始化 WebSocket 连接
useEffect(() => {
if (!url) return;
wsRef.current = new WebSocket(url);
wsRef.current.onopen = () => {
console.log(`WebSocket connected to ${url}`);
setIsConnected(true);
};
wsRef.current.onmessage = (event) => {
setLastMessage(event.data);
};
wsRef.current.onerror = (err) => {
console.error(`WebSocket error on ${url}`, err);
setError(`Error: ${err}`);
};
wsRef.current.onclose = () => {
console.log(`WebSocket disconnected from ${url}`);
setIsConnected(false);
};
// 组件卸载时,关闭 WebSocket 连接
return () => {
wsRef.current?.close();
wsRef.current = null;
};
}, [url]);
// 发送消息的函数
const sendMessage = useCallback((message: string) => {
if (wsRef.current?.readyState === WebSocket.OPEN) {
wsRef.current.send(message);
} else {
console.warn(`WebSocket is not open. Unable to send message: ${message}`);
}
}, []);
return {
isConnected,
lastMessage,
sendMessage,
error,
};
};
export default useWebSocket;
使用示例:
你可以通过 useWebSocket
钩子在组件中使用 WebSocket 功能,轻松地连接、接收消息和发送消息。
import React, { useEffect } from 'react';
import useWebSocket from './useWebSocket';
const WebSocketComponent = () => {
const { isConnected, lastMessage, sendMessage, error } = useWebSocket('ws://example.com/first');
useEffect(() => {
// WebSocket 连接后发送一条消息
if (isConnected) {
sendMessage('Hello, WebSocket!');
}
}, [isConnected, sendMessage]);
// 每次 lastMessage 更新时,打印接收到的数据
useEffect(() => {
if (lastMessage) {
console.log('Received message:', lastMessage);
}
}, [lastMessage]);
return (
<div>
<h1>WebSocket 实时数据</h1>
<p>连接状态: {isConnected ? '已连接' : '未连接'}</p>
<p>最近消息: {lastMessage || '暂未收到消息'}</p>
{error && <p>错误: {error}</p>}
<button onClick={() => sendMessage('Another message')}>发送消息</button>
</div>
);
};
export default WebSocketComponent;