React接收Spring Server-Sent Events时消息重复,每秒6条相同消息求助
为什么React的EventSource会每秒收到多条相同的SSE消息?
看起来你的问题核心出在组件渲染时重复创建EventSource连接,以及useEffect缺少依赖数组导致的重复事件绑定上,咱们一步步拆解原因并给出修复方案:
问题根源分析
重复创建多个SSE连接
你在组件函数的顶层直接声明了plotDataEventSource,这意味着每次组件重新渲染(比如调用setData更新状态、父组件触发渲染等),都会新建一个EventSource实例去连接后端的SSE端点。如果你的组件每秒因为状态更新触发6次渲染,就会同时存在6个活跃的SSE连接——每个连接都会收到后端每秒发送的那条消息,自然控制台会打印6条完全相同的内容。useEffect无依赖数组,重复绑定事件
你的useEffect没有指定依赖数组,这会导致每次组件渲染时都会重新执行这个effect,重复给onmessage事件赋值。虽然这不是多条消息的主因,但会造成不必要的资源消耗,还可能引发其他潜在问题。
修复方案
你需要用useRef来持久化保存EventSource实例,确保整个组件生命周期内只有一个活跃连接,同时在useEffect里规范管理连接的创建与销毁:
import { useEffect, useRef, useState } from 'react'; const Component = () => { const [data, setData] = useState([]); // 用useRef保存EventSource实例,避免组件渲染时重复创建 const eventSourceRef = useRef(null); useEffect(() => { // 仅在第一次渲染时初始化SSE连接 if (!eventSourceRef.current) { eventSourceRef.current = new EventSource( "http://localhost:8080/tags/plot/antenna" ); eventSourceRef.current.onmessage = e => { console.log(e); setData(prevState => { /* 你的数据处理逻辑 */ return [...prevState, JSON.parse(e.data)]; // 示例处理方式 }); }; // 处理连接错误,避免无效连接占用资源 eventSourceRef.current.onerror = err => { console.error('SSE连接出错:', err); eventSourceRef.current.close(); eventSourceRef.current = null; }; } // 组件卸载时主动关闭SSE连接,清理资源 return () => { if (eventSourceRef.current) { eventSourceRef.current.close(); eventSourceRef.current = null; } }; }, []); // 空依赖数组,确保effect仅执行一次 return ( /* 你的图表渲染代码 */ ); }
额外验证小技巧
你可以在组件函数里加一行console.log('组件渲染了'),看看是不是每秒确实会触发6次渲染——这能直接验证咱们对重复连接的判断。另外后端的Flux逻辑是正常的(Chrome直接访问能拿到单条消息),所以问题完全出在前端的连接管理上。
内容的提问来源于stack exchange,提问作者Matt
相关产品推荐
相关产品推荐

