React 17中useMemo创建EventSource出现重复实例问题求助
React开发模式下useMemo执行两次导致EventSource重复创建的问题
原因分析
这是React开发模式下StrictMode的默认行为。StrictMode会刻意重复执行部分函数(包括useMemo的回调、组件渲染函数、useState初始化函数等),目的是提前帮你排查潜在的副作用问题——比如未清理的定时器、重复创建的资源连接这类容易引发内存泄漏的场景。
你的问题对应场景
你用useMemo缓存EventSource实例时,StrictMode触发了两次useMemo回调,导致创建了两个连接;而你只能拿到第二次的实例引用,第一个连接自然无法关闭,最终引发内存泄漏。哪怕是简化的测试代码,useMemo里的setInterval也会因为StrictMode的重复执行,打印出两个不同的随机值。
解决方式
- 生产环境自动消失:StrictMode仅在开发环境生效,生产打包后不会有这个重复执行的逻辑,上线后双连接问题会自动解决。
- 添加资源清理逻辑:如果想在开发阶段避免内存泄漏,可以配合useEffect给EventSource加上清理函数,确保所有创建的连接都能被关闭:
// 假设你用ref存EventSource实例 const eventSourceRef = useRef(eventSource); useEffect(() => { const source = eventSourceRef.current; return () => { source?.close(); }; }, [eventSourceRef]);
- 临时关闭StrictMode(不推荐):如果开发阶段必须避免重复执行,可以暂时移除项目入口处的
<StrictMode>标签,但不建议长期这么做——StrictMode能帮你提前发现很多上线后才会暴露的潜在问题。
额外说明
StrictMode重复执行的范围包括:
- 组件的渲染函数
- useState、useMemo、useReducer的初始化回调
- useEffect的清理函数
这种设计是为了让开发者更容易发现那些没有被正确处理的副作用,比如你遇到的未关闭的EventSource连接,提前修复能避免生产环境出现更严重的问题。
内容的提问来源于stack exchange,提问作者Matthieu
相关产品推荐
相关产品推荐

