【问题标题】:Socket.io Callbacks with react带有反应的 Socket.io 回调
【发布时间】:2018-12-12 07:01:35
【问题描述】:

我正在使用带有反应的 Socket.io 回调。但是,有时我会收到此警告

警告:无法在未安装的设备上调用 setState(或 forceUpdate) 零件。这是一个无操作,但它表明您的内存泄漏 应用。要修复,取消所有订阅和异步任务 在 componentWillUnmount 方法中。

从根本上说,我理解回调可以持有对本地数据的引用,并防止该数据被清除,直到回调被清除。

不幸的是,Socket.io 不能使用 Promise,而是使用直接回调。这意味着我可能会在组件卸载后收到回调,因为这些回调无法“取消”

我确保服务器响应所有回调以确保它们得到满足,因此不会泄漏内存

我试图通过在componentDidMount 中调用this.setState({mounted:true}); 和在componentWillUnmount 中调用this.setState({mounted:false}); 来“消除”此警告

然后在我的更新中,只需在 socket.io 回调中调用 this.setState() 之前检查 if(this.state.mounted)

这适用于大多数情况。但是,似乎在这种情况下。父组件导致这个组件

  • componentDidMount
    • 更新状态为mounted:true
    • 向socket.io发送请求 -componentWillUnmount
    • 更新状态为mounted:false
  • componentDidMount
    • 更新状态为mounted:true
    • 向 socket.io 发送额外请求
  • 来自 socket.io 的回调响应
    • 警告打印

如何防止这种情况发生? sock.io 有没有更好的设计模式

【问题讨论】:

  • 我不确定具体方法,但也许你可以在调用componentWillUnmount 时使用off“取消监听”某些事件,这样你就没有闲置的听众了。
  • 是的,这不是一个事件,而是对 socket.io 的回调响应。因此客户端向服务器发送一个包含回调函数的事件。然后服务器可以随时调用回调函数。

标签: reactjs socket.io


【解决方案1】:

基于this 到另一个与socket.io 相关的问题,我想说的是,您可能希望在组件卸载时实际断开与服务器的连接,而不是检查安装状态,然后基于调用setState。正如您现在所拥有的那样,即使不再安装组件,服务器仍会响应该事件,但是如果您在卸载组件时断开连接,则根本不会从服务器发送任何数据。

注意:我自己没有尝试过,所以我不能肯定这会奏效,但根据上述答案,我相信这可能会解决您的问题。

【讨论】:

  • 我在许多其他组件中使用相同的套接字,对于单页应用程序,因此在这种情况下断开连接并不是一个真正可行的选择。
【解决方案2】:

我在这里找到了回复:

Is there a way to check if the react component is unmounted?

他们建议使用:

this._ismounted = true;
this._ismounted = false;

而不是调用异步的 this.setState()

看来你应该从文档https://reactjs.org/docs/react-component.html

你不应该在 componentWillUnmount() 中调用 setState(),因为组件永远不会被重新渲染。一旦组件实例被卸载,它将永远不会被再次装载。

【讨论】:

    猜你喜欢
    • 2013-12-21
    • 1970-01-01
    • 1970-01-01
    • 2017-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-15
    • 1970-01-01
    相关资源
    最近更新 更多