如何使用套接字触发反应,重新呈现UI?

时间:2016-12-07 02:35:48

标签: reactjs websocket socket.io redux

这是我的工作代码:

import socket from 'components/io/socket';
import store from 'components/store';
// globally available socket connection
class ChatBox extends React.Component {
  componentDidMount(){
     socket.on("message", this.props.addChat.bind(this));
     // this.props.addChat is reduxer actions.
  }
}

但是,我担心这样的代码可能会引入内存泄漏,因为旧的ChatBox组件仍然会被套接字引用。

我试图将其改为:

import socket from 'components/io/socket';
import store from 'components/store';
socket.on("message", store.dispatch(addChat({...}))

class ChatBox extends React.Component {
  render(){ ... }
}

然而,第二个代码不会触发html被重新呈现,即使我使用断点,并且在套接字收到消息后调用store.getState()结果更改。

1 个答案:

答案 0 :(得分:1)

您可以覆盖componentWillUnmmount取消订阅侦听器,从而使套接字释放对您担心的ChatBox的引用。

但是,由于每次调用bind都会创建一个全新的实例,因此您不会在componentWillUnmmount处获得侦听器引用。要解决此问题,请在构造函数中绑定方法。

constructor(props) {
  super(props);

  this.addChat = this.props.addChat.bind(this);
}

componentDidMount() {
  socket.on("message", this.addChat);
}

componentWillUnmount() {
  socket.off("message", this.addChat); // or whatever it is called
}

无论如何,对于我来说,绑定到组件的外部方法(从props外部传递)似乎很奇怪。通常您订阅组件本身的方法,因此您可以确定发生了什么 - 特别是因为该方法可以自由地更改实例的任何属性,例如addChat绑定的状态或事件。所以,您可能需要对此进行审核。也许转换为高阶组件?