使用Socket.io和React使用属性如何正确管理生命周期

时间:2018-04-23 18:40:02

标签: reactjs socket.io

我正在使用socket.io,我有一个使用属性作为ID键的组件,如this.props.dataKey,以确定要订阅的Web套接字路径。

var path = "/data/" + this.props.dataKey + "/subdata"
socket.on(path, handleData.bind(this));

我注意到的一件事是,在卸载组件时会调用handleData函数,因此我在componentWillUnmount

上添加了取消订阅调用

但是,如果数据键属性发生更改,我也想处理它并取消订阅旧路径并订阅新路径。

我首先使用componentWillUpdatecomponentWillMount来跟踪订阅/取消订阅,但我注意到这些日期在16.3中被标记为已弃用

所以我开始使用getDerivedStateFromProps写入状态,如果属性state = {path,lastpath, subscribed},然后在渲染方法中订阅!订阅取消订阅到最后一个路径并订阅新路径

if(!this.state.subscribed)
{
    if(this.state.lastpath){socket.removeListener(this.state.lastpath);}
     socket.on(this.state.path, handleData.bind(this));
    this.setState({subscribed:true});
}

不幸的是我得到一个警告,说在渲染中设置状态是一个anit-pattern,我应该使用componentWillMount。但是componentWillMount仅在创建时触发,而不是在更新时触发,这意味着更改的道具效果不会受到影响。另外,不推荐使用componentWillMoutn和componentWillUpdate。那么处理这个问题的适当场所是什么?它无法在getDerrivedStateFromProps中处理,这是一个静态函数。

1 个答案:

答案 0 :(得分:1)

我认为你走在正确的轨道上

class Component extends React.Component {
  static propTypes = {
    dataKey: PropTypes.string.isRequired
  }

 state = {
   dataKey: false
 }

 getDerivedStateFromProps(nextProps, prevState) {
   return {
     dataKey: nextProps.dataKey
   }
 }

componentDidUpdate(prevProps, prevState) {
 if (this.state.dataKey !== prevState.dataKey) {
     this.subscribe(this.state.dataKey)
   }

   if(prevState.dataKey && this.state.dataKey &&
     prevState.dataKey !== this.state.dataKey) {
      this.unsubscribe(prevState.dataKey)
   }
}

 componentWillUnmount() {
   this.unsubscribe(this.state.dataKey)
 }

 subscribe(key) {
   const path = `/data/${key}/subdata`
   socket.on(path, this.handleData.bind(this));
 }

 handleData(data) {
  console.log(data)
 }

 unsubscribe(key) {
  socket.unsubscribe(key)
 }

}

Dan Abramov的地图可以提供帮助

enter image description here