我有一个简单的示例,其中包含服务器发送事件服务器每 5 秒发送一次更新,以及一个监听它的 React 应用程序。每次调用 useEffect
时,React 应用程序似乎都会添加一个新的监听器,同时保留旧的监听器,这显然会使应用程序很快崩溃。
我已经尝试添加一个监听状态变量,并且只在没有监听的情况下进行订阅,并且只在页面首次加载时触发 useEffect
。在这些情况下,数据将停止正确更新。
服务器.js
const http = require("http");
http
.createServer((request, response) => {
console.log("Requested url: " + request.url);
if (request.url.toLowerCase() === "/events") {
response.writeHead(200, {
Connection: "keep-alive",
"Content-Type": "text/event-stream",
"Cache-Control": "no-cache",
"Access-Control-Allow-Origin": "*"
});
setInterval(() => {
console.log('interval')
response.write("event: scan\n");
response.write("\n\n");
}, 5000);
}
})
.listen(5000, () => {
console.log("Server running at http://127.0.0.1:5000/");
});
应用程序.js
import React, { useState, useEffect } from 'react';
import './App.css';
function App() {
const [data, setData] = useState([0])
const [eventSource, setEventSource] = useState(new EventSource("http://127.0.0.1:5000/events"));
useEffect(() => {
console.log('render')
eventSource.addEventListener('scan', event => {
setData([data[0] + 1, ...data]);
});
}, [data]);
return (
<div> { data } </div>
);
}
export default App;
最佳答案
事实证明它比我最初想象的要复杂得多,所以我没有重新发明轮子,而是找到了包 react-hooks-sse .解决方案如下所示:
import React, { useState, useEffect } from 'react';
import { useSSE, SSEProvider } from 'react-hooks-sse';
import './App.css';
const Component = () => {
const state = useSSE('scan');
const [data, setData] = useState([])
useEffect(() =>{
if (state) {
setData([state.data.some.value ,...data]);
}
}, [state])
return data
}
function App() {
return (
<SSEProvider endpoint="http://127.0.0.1:5000/events" >
<Component />
</SSEProvider>
);
}
export default App;
state
变量在技术上只是从服务器收到的最新消息。
关于javascript - 停止在 React 应用程序中使用重新订阅的事件源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56965559/