实时 React Hooks:SSE, WebSocket & SWR 模式 - Openclaw Skills
作者:互联网
2026-03-30
什么是 实时 React Hooks?
实时 React Hooks 为 React 应用集成实时数据提供了一套稳健的模式。通过利用 Openclaw Skills 的这一资源,开发者可以实现具有专业级重连逻辑和错误处理的服务器发送事件 (SSE) 和 WebSockets。
该技能专注于性能和可靠性,确保 UI 状态与后端数据源保持同步,无需手动刷新页面。它处理了连接生命周期、状态管理和乐观 UI 更新的复杂性,让开发者能够专注于构建功能而非基础设施。
下载入口:https://github.com/openclaw/skills/tree/main/skills/wpank/realtime-react-hooks
安装与下载
1. ClawHub CLI
从源直接安装技能的最快方式。
npx clawhub@latest install realtime-react-hooks
2. 手动安装
将技能文件夹复制到以下位置之一
全局模式~/.openclaw/skills/
工作区
/skills/
优先级:工作区 > 本地 > 内置
3. 提示词安装
将此提示词复制到 OpenClaw 即可自动安装。
请帮我使用 Clawhub 安装 realtime-react-hooks。如果尚未安装 Clawhub,请先安装(npm i -g clawhub)。
实时 React Hooks 应用场景
- 构建具有实时性能指标的动态仪表盘。
- 实现聊天界面和即时通知系统。
- 创建具有流式价格更新的金融应用。
- 开发 UI 必须即时反映多用户更改的协作工具。
- 使用目标端点 URL 初始化所需的 Hook(SSE 或 WebSocket)。
- Hook 建立持久连接并管理生命周期,包括组件卸载时的自动清理。
- 传入数据会被自动解析并存储在 React 状态或 SWR 缓存中。
- 如果连接丢失,重连逻辑将呈指数级触发,确保稳定性。
- UI 对状态变化做出反应,可选择使用乐观更新来提供无延迟体验。
实时 React Hooks 配置指南
要将此技能添加到您的项目中,请使用 Openclaw Skills CLI:
npx clawhub@latest install realtime-react-hooks
实时 React Hooks 数据架构与分类体系
| 特性 | 描述 | 管理的关键数据 |
|---|---|---|
| useSSE | 服务器发送事件 Hook | data, isConnected, close |
| useWebSocket | 全双工 WS Hook | isConnected, send, retriesRef |
| useRealtimeData | SWR + SSE 集成 | data, mutate, isValidating |
| useSubscription | 基于频道的编程 | channels, onEvent, isConnected |
name: realtime-react-hooks
model: standard
description: React hooks for real-time data with SSE, WebSocket, and SWR integration. Covers connection management, reconnection logic, and optimistic updates. Use when building React apps with real-time features. Triggers on SSE hook, WebSocket hook, real-time React, useEventSource, live updates.
Real-Time React Hooks
Production patterns for real-time data in React applications using SSE, WebSocket, and SWR.
Installation
OpenClaw / Moltbot / Clawbot
npx clawhub@latest install realtime-react-hooks
When to Use
- React apps needing live data updates
- Dashboards with real-time metrics
- Chat interfaces, notifications
- Any UI that should update without refresh
Pattern 1: SSE Hook
import { useEffect, useRef, useState, useCallback } from 'react';
interface UseSSEOptions {
url: string;
onMessage?: (data: T) => void;
onError?: (error: Event) => void;
enabled?: boolean;
}
export function useSSE({
url,
onMessage,
onError,
enabled = true,
}: UseSSEOptions) {
const [data, setData] = useState(null);
const [isConnected, setIsConnected] = useState(false);
const eventSourceRef = useRef(null);
useEffect(() => {
if (!enabled) return;
const eventSource = new EventSource(url);
eventSourceRef.current = eventSource;
eventSource.onopen = () => {
setIsConnected(true);
};
eventSource.onmessage = (event) => {
try {
const parsed = JSON.parse(event.data) as T;
setData(parsed);
onMessage?.(parsed);
} catch (e) {
console.error('SSE parse error:', e);
}
};
eventSource.onerror = (error) => {
setIsConnected(false);
onError?.(error);
};
return () => {
eventSource.close();
eventSourceRef.current = null;
};
}, [url, enabled]);
const close = useCallback(() => {
eventSourceRef.current?.close();
setIsConnected(false);
}, []);
return { data, isConnected, close };
}
Pattern 2: WebSocket Hook with Reconnection
interface UseWebSocketOptions {
url: string;
onMessage?: (data: unknown) => void;
reconnect?: boolean;
maxRetries?: number;
}
export function useWebSocket({
url,
onMessage,
reconnect = true,
maxRetries = 5,
}: UseWebSocketOptions) {
const [isConnected, setIsConnected] = useState(false);
const wsRef = useRef(null);
const retriesRef = useRef(0);
const connect = useCallback(() => {
const ws = new WebSocket(url);
wsRef.current = ws;
ws.onopen = () => {
setIsConnected(true);
retriesRef.current = 0;
};
ws.onmessage = (event) => {
try {
const data = JSON.parse(event.data);
onMessage?.(data);
} catch {
onMessage?.(event.data);
}
};
ws.onclose = () => {
setIsConnected(false);
if (reconnect && retriesRef.current < maxRetries) {
retriesRef.current++;
const delay = Math.min(1000 * 2 ** retriesRef.current, 30000);
setTimeout(connect, delay);
}
};
ws.onerror = () => {
ws.close();
};
}, [url, onMessage, reconnect, maxRetries]);
useEffect(() => {
connect();
return () => wsRef.current?.close();
}, [connect]);
const send = useCallback((data: unknown) => {
if (wsRef.current?.readyState === WebSocket.OPEN) {
wsRef.current.send(JSON.stringify(data));
}
}, []);
return { isConnected, send };
}
Pattern 3: SWR with Real-Time Updates
import useSWR from 'swr';
import { useEffect } from 'react';
export function useRealtimeData(
key: string,
fetcher: () => Promise
) {
const { data, mutate, ...rest } = useSWR(key, fetcher);
// Subscribe to real-time updates
useEffect(() => {
const eventSource = new EventSource(`/api/events/${key}`);
eventSource.onmessage = (event) => {
const update = JSON.parse(event.data);
// Optimistically update cache
mutate((current) => {
if (!current) return update;
return { ...current, ...update };
}, false); // false = don't revalidate
};
return () => eventSource.close();
}, [key, mutate]);
return { data, mutate, ...rest };
}
Pattern 4: Subscription Hook
interface UseSubscriptionOptions {
channels: string[];
onEvent: (channel: string, data: unknown) => void;
}
export function useSubscription({ channels, onEvent }: UseSubscriptionOptions) {
const { send, isConnected } = useWebSocket({
url: '/api/ws',
onMessage: (msg: any) => {
if (msg.type === 'event') {
onEvent(msg.channel, msg.data);
}
},
});
useEffect(() => {
if (!isConnected) return;
// Subscribe to channels
channels.forEach((channel) => {
send({ type: 'subscribe', channel });
});
return () => {
channels.forEach((channel) => {
send({ type: 'unsubscribe', channel });
});
};
}, [channels, isConnected, send]);
return { isConnected };
}
Pattern 5: Connection Status Indicator
export function ConnectionStatus({ isConnected }: { isConnected: boolean }) {
return (
{isConnected ? 'Live' : 'Disconnected'}
);
}
Related Skills
- Meta-skill: ai/skills/meta/realtime-dashboard/ — Complete realtime dashboard guide
- resilient-connections — Retry logic
- design-systems/animated-financial-display — Number animations
NEVER Do
- NEVER forget cleanup — Always close connections on unmount
- NEVER reconnect infinitely — Use max retries with exponential backoff
- NEVER parse without try/catch — Server might send malformed data
- NEVER mutate and revalidate — Use
mutate(data, false)for optimistic updates - NEVER ignore connection state — Show users when they're disconnected
Quick Reference
// SSE
const { data, isConnected } = useSSE({ url: '/api/events' });
// WebSocket
const { isConnected, send } = useWebSocket({
url: 'wss://api.example.com/ws',
onMessage: (data) => console.log(data),
});
// SWR + Real-time
const { data } = useRealtimeData('metrics', fetchMetrics);
// Subscriptions
useSubscription({
channels: ['user:123', 'global'],
onEvent: (channel, data) => updateState(channel, data),
});
相关推荐
专题
+ 收藏
+ 收藏
+ 收藏
+ 收藏
+ 收藏
最新数据
相关文章
小红书文案教练:爆款笔记生成器 - Openclaw Skills
慕尼黑 MVG & S-Bahn 实时追踪命令行工具 - Openclaw Skills
Reddit 研究技能:自动化社群洞察 - Openclaw Skills
豆包聊天:带有联网搜索功能的免费 AI 对话 - Openclaw Skills
NightPatch:自动化工作流优化 - Openclaw 技能
国产 AI 视频生成器:Wan2.6 与可灵集成 - Openclaw Skills
Sonos Announce:智能音频状态恢复 - Openclaw Skills
Hypha Payment:P2P 代理协作与 USDT 结算 - Openclaw Skills
Cashu Emoji:隐藏代币编解码 - Openclaw Skills
技术 SEO 精通:审计、修复与监控 - Openclaw Skills
AI精选
