- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
设置:
问题:
Navbar 监听套接字事件以更新未读消息的计数器。一切正常,直到用户导航到不同的页面。一旦发生导航,即使连接完好无损,导航栏中的套接字(永远不会卸载)也不会响应服务器发出的 future 事件。
预期行为:
导航栏套接字在页面导航后仍然响应服务器发出的信号。
观察:
即使导航栏套接字没有响应,应用程序中使用套接字的其他区域仍然可以正常工作。刷新页面时导航栏套接字再次响应,但在页面导航后重复出现相同的问题。导航栏是唯一在发生导航时不会卸载的组件,而安装在导航上的组件是通过 useContext 使用套接字实例加载的。
据我所知,连接永远不会中断(断开事件永远不会在服务器端触发)并且新安装的组件可以发出一个事件,服务器响应,并向新组件响应的客户端发出响应,同时导航栏没有。
其他注意事项:
这是我问过的第一个问题,如果问题格式不正确,我提前道歉。代码显然已简化,以省略似乎不会影响问题的区域。省略了服务器端代码,因为它似乎可以毫无问题地接收和发出事件。
//App.js
const App = () => {
const socket = useRef(io('path'));
return (
<SocketContext.Provider value={socket.current}>
<BrowserRouter>
<Nav />
<Switch>
<Route path='/messages' component={Messages} />
<Route path='/' component={Home} />
<!-- Other routes -->
</Switch>
</BrowserRouter>
</SocketContext.Provider>
)
}
//Nav.js
const Nav = () => {
const socket = useContext(SocketContext);
const [newMsgCount, setNewMsgCount] = useState(0);
useEffect(() => {
socket.emit('get new msg count');
socket.on('new msg count', (count) => setNewMsgCount(count));
socket.on('new msg received', () => setNewMsgCount(prev => prev + 1));
socket.on('marked as read', () => setNewMsgCount(prev => prev - 1));
return () => {
socket.off('new msg count');
socket.off('new msg received');
socket.off('marked as read');
}
}, [socket]);
return (
//Omitted for brevity
)
}
//Messages.js
const Messages = () => {
const socket = useContext(SocketContext);
const [msgs, setMsgs] = useState([]);
const [newMsg, setNewMsg] = useState({ to: '', body: '' });
useEffect(() => {
socket.emit('get all msgs');
socket.on('all msgs', (data) => setMsgs(data));
socket.on('new msg received', (data) => setMsgs(prev => ([...prev, data])));
return () => {
socket.off('all msgs');
socket.off('received new msg');
}
}, [socket]);
const send = () => socket.emit('new msg', newMsg);
return (
<div>
<!-- Omitted for brevity -->
<form onSubmit={send}>
<!-- Omitted for brevity -->
<button>Send</button>
</form>
</div>
)
}
最佳答案
您没有正确断开/取消订阅套接字。 socket.off
接受两个参数,第二个是您要断开连接/取消监听/取消订阅事件的监听器回调。
socket.off(eventName, listener)
Removes the specified listener from the listener array for the eventnamed eventName.
const listener = (...args) => {
console.log(args);
}
socket.on("details", listener);
// and then later...
socket.off("details", listener);
将监听器重构为可传递给 socket.on
和 socket.off
的独立函数>.
导航.js
const Nav = () => {
const socket = useContext(SocketContext);
const [newMsgCount, setNewMsgCount] = useState(0);
useEffect(() => {
socket.emit('get new msg count');
const incrementCount = () => setNewMsgCount(prev => prev + 1);
const decrementCount = () => setNewMsgCount(prev => prev - 1);
socket.on('new msg count', setNewMsgCount);
socket.on('new msg received', incrementCount);
socket.on('marked as read', decrementCount);
return () => {
socket.off('new msg count', setNewMsgCount);
socket.off('new msg received', incrementCount);
socket.off('marked as read', decrementCount);
}
}, [socket]);
...
}
消息.js
const Messages = () => {
const socket = useContext(SocketContext);
const [msgs, setMsgs] = useState([]);
const [newMsg, setNewMsg] = useState({ to: '', body: '' });
useEffect(() => {
socket.emit('get all msgs');
const messageRecdHandler = (data) => setMsgs(prev => ([...prev, data]));
socket.on('all msgs', setMsgs);
socket.on('new msg received', messageRecdHandler);
return () => {
socket.off('all msgs', setMsgs);
socket.off('received new msg', messageRecdHandler);
}
}, [socket]);
const send = () => socket.emit('new msg', newMsg);
...
}
我同意 Silven 的观点,即套接字可能应该从父 React 组件代码中移出。将其实例化一次并将其设置为单例的上下文值。
关于javascript - Socket.io 连接完好无损,但从不卸载的 React 组件在页面导航后变得对套接字事件无响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71239032/
1.使用start-all.sh启动hadoop服务时,提示输入 您确定要继续连接吗(是/否) 当我通过脚本启动它时如何抑制这个提示,现在我正在使用期望模块,但我认为可能有一种更简单的方法来做到这一点
我安装了在 Ubuntu 12.04 下运行的 Geonode R 2.01。我尝试使用以下命令卸载它: sudo apt-get remove --purge geonode sudo apt-ge
假设我有 AppDomainA,它启动 AppDomainB。 AppDomainB 然后启动 AppDomainC。 如果在 AppDomainA 中卸载 AppDomainB,AppDomainC
关闭。这个问题是off-topic .它目前不接受答案。 想改善这个问题吗? Update the question所以它是 on-topic对于堆栈溢出。 8年前关闭。 Improve this q
我尝试使用以下命令从我的 Ubuntu 中卸载 NGinX: sudo apt-get remove nginx-core nginx-full nginx-light nginx-extras n
我已经从 /Applications/ 中删除了 MacVim目录,但当我输入 vim 时在终端中显示错误:no such file or directory: /Applications/MacVi
我的页面中有一个 iframe,该 iframe 嵌入了一个不在我的服务器上的网站。 我正在寻找一种在 iframe 重定向之前触发函数的方法。例如,当用户单击 iframe 内的链接并且 ifram
看来我被 Visual Studio 的 Atomineer Pro 文档加载项挟持了!试用期结束了,我没有用了!但现在每次我在 Visual Studio 中做某事时,我都会收到一条错误消息并发送到
我有一个使用 WiX 完成的安装程序。安装完成后,它会启动一个应用程序,在 Explorer 进程中注入(inject)一些代码。 目前,当我卸载时,重新启动管理器会启动并关闭我的应用程序和资源管理器
在我的网络应用中,我需要在用户离开页面之前发送他们更改的最新数据。 我在页面卸载时调用这样的函数: window.onbeforeunload=sendData; 这就是函数内部调用的内容 funct
我使用 jQuery 和 history.js 来管理部分页面之间的动态转换;这样我就可以避免重新加载整个文档。其中一些部分页面调用自己独特的 javascript 文件。虽然页面之间的转换运行良好,
我需要处理应用程序包的变化,我这样写我的 mainfest mainfest.xml 我的接收器类
我目前在使用大量内存方面遇到了麻烦,我正在尽一切努力削减和优化涉及内存的代码...目前我的游戏的大部分 Nib 文件都加载了所有它在 ViewDidLoad 中的变量,现在我的问题是,在我的 view
如何从系统中删除 composer Php Dependecny Manager? 它说卸载无法继续,因为以下应用程序正在使用需要删除的文件。 Windows 资源管理器 最佳答案 我遇到了同样的问题
所以我使用 stow 在服务器上安装了 Python 2.7.1 源代码 .我过去很粗心,在处理源代码安装时我试图保持井井有条。所以,输入 stow。现在我使用 wget 安装了 easy_insta
有谁知道如何卸载 MacRuby?我在使用 RubyCocoa 然后决定试用 MacRuby,在安装 MacRuby 之后,RubyCocoa 已经停止工作。所以我想删除 MacRuby,但我找不到任
我无法从 64 位 EC2 卸载 mongo。在/usr/bin 我有 mongo 和 mongod 等等。当我从任何地方键入 mongo 时,它会在 1.8 版打开 shell。我现在下载了 2.0
本文实例讲述了Android编程实现监控apk安装,卸载,替换的方法。分享给大家供大家参考,具体如下: ?
1说明 mysql++是mysql开发团队为OO编程提供的C++开发库,是对mysql提供的底层数据存取API进行的C++封装,用其手册上的说法是:复杂而又庞大,当然功能也更强大。 Mysql+
自从我开始建立我的网站那天起,我安装了很多包,有时是为了测试一堆代码,有时是为了项目本身(后来我发现这不是需要的包)。但是现在,当我运行 pip freeze 时,我有一个包列表,我很难卸载不使用的包
我是一名优秀的程序员,十分优秀!