reactjs - 带有反应的 Socket.io 回调
问题描述
我正在使用带有反应的 Socket.io 回调。但是,有时我会收到此警告
警告:无法在未安装的组件上调用 setState(或 forceUpdate)。这是一个空操作,但它表明您的应用程序中存在内存泄漏。要修复,请取消 componentWillUnmount 方法中的所有订阅和异步任务。
从根本上说,我知道回调可以持有对本地数据的引用,并防止该数据被清除,直到回调被清除。
不幸的是,Socket.io 不能使用 Promise,而是使用直接回调。这意味着我可能会在组件卸载后收到回调,因为这些回调无法“取消”
我确保服务器响应所有回调以确保它们得到满足,因此不会泄漏内存
我试图通过调用来“消除this.setState({mounted:true});
”这个componentDidMount
警告 this.setState({mounted:false});
componentWillUnmount
然后在我的更新中,只需在 socket.io 回调中if(this.state.mounted)
调用之前进行检查。this.setState()
这适用于大多数情况。但是,似乎在这种情况下。父组件导致该组件
- 组件DidMount
- 将状态更新为mounted:true
- 向 socket.io -componentWillUnmount 发送请求
- 将状态更新为mounted:false
- 组件DidMount
- 将状态更新为mounted:true
- 向 socket.io 发送附加请求
- 来自 socket.io 的回调响应
- 打印警告
我该如何防止这种情况?sock.io 有更好的设计模式吗
解决方案
基于thissetState
to another socket.io related question,我想说的是,您可能希望在组件卸载时实际断开与服务器的连接,而不是检查已安装状态然后基于该调用。正如您现在所拥有的那样,即使不再安装组件,服务器仍会响应该事件,但是如果您在卸载组件时断开连接,则根本不会从服务器发送任何数据。
注意:我自己没有尝试过,所以我不能肯定这会起作用,但根据上面的答案,我相信这可能会解决你的问题。
推荐阅读
- javascript - 使用简单的javascript返回格式化日期('YYYY-MM-DD')获取fromDate和toDate之间的日期
- sql-server - 编写通用存储过程以从表中获取值的缺点
- android - 此版本中使用了已弃用的 Gradle 功能,使其与 Gradle 6.0 不兼容?当我降级 gradle 版本时
- django - 在 django_admin_log 中添加页面查看记录和更改详情
- redis - Redis MATCH操作中如何使用OR条件
- ajax - 在wordpress中将数组从ajax传递到php
- angular - Angular Reactive Forms 控件与 Get
- javascript - 带单选按钮的角度动态 html 绑定
- c - 在 C 中设置 open() 系统调用的权限
- javascript - 无法在浏览器上运行的 Swiper 已调整为 chrome 中的智能手机视图