【问题标题】:Socket.io not removing listener from every react componentSocket.io 没有从每个反应组件中删除监听器
【发布时间】:2019-02-01 05:18:39
【问题描述】:

我想从 socket.io 客户端创建off 方法,以从所有反应组件中删除所有匹配运行的侦听器因为目前我正在两个不同的组件上侦听相同的事件,它们都在 componentDidMount 中,

Board.js

 socket.on('achievement', (data) => {
                const updateAchievement= [data, ...this.state.getAchievements];
                this.setState({
                    recentAchievements: this.state.recentAchievements.concat(data),
                    getAchievements: updateAchievement
                });
            });

仪表板.js

 socket.on('achievement', (data) => {
                const updateAchievement= [data, ...this.state.getAchievements];
                this.setState({
                    recentAchievements: this.state.recentAchievements.concat(data),
                    getAchievements: updateAchievement
                });
            });

目前,如果最终用户在 DashBoard.js 上关闭监听事件,Board.js 仍在积极接收我不想要的数据。 board.js 组件始终在视图中,这就是为什么我可以看到数据仍在出现的原因。

我如何退订

仪表板.js

componentWillUnmount(){
            socket.off("achievement");
     }

就像我上面说的,Board 组件始终在视图中,我仍然可以看到传入的数据。

我怎样才能阻止这种情况?

【问题讨论】:

  • 您在哪里以及如何取消订阅处理程序?
  • @heydude101 您需要提供要取消订阅的处理程序。仅'achievement' 不足以提供给off(),因为有多个处理程序正在监听该事件。看我的回答。
  • 就像@trinx 在他的回答中所说,您没有使用正确的函数签名。正确的是:socket.off(eventName, functionTo UnsubscribeFrom) 由于您没有提供第二个参数,因此不会删除任何处理程序
  • 我并没有真正使用任何函数,我只是将侦听器放在 didMount 中,但我遵循了 trixn 的回答,仍然在做同样的事情。
  • @heydude101 不清楚您要什么。您想删除用户操作的所有侦听器吗?

标签: javascript reactjs socket.io


【解决方案1】:

只需使用 componentWillUnmout() 生命周期方法通过处理程序调用 socket.off()。请注意,off() 要求将先前订阅的处理程序作为第二个参数传递:

class MyComponent extends Component {
    updateAchievement = data => {
        this.setState(prevState => ({
                    recentAchievements: [...prevState.recentAchievements, data],
                    getAchievements: [data, ...prevState.getAchievements]
        }));
    }

    componentDidMount() {
       socket.on('achievement', this.updateAchievement);
    }

    componentWillUnmount() {
       socket.off('achievement', this.updateAchievement);
    }

    // ...
}

请注意,更新状态时不应使用this.state。始终使用setState 的版本,该版本接受一个函数,其中第一个参数是先前的状态并基于该状态进行更新。

【讨论】:

  • 我按照这个答案仍然在做同样的事情
  • 您需要在两个组件中执行此操作以停止监听两个组件。请更新您的问题以包含新代码
猜你喜欢
  • 2012-08-25
  • 2016-12-25
  • 2014-05-30
  • 2019-04-11
  • 2017-08-17
  • 1970-01-01
  • 2021-11-10
  • 2019-02-07
  • 1970-01-01
相关资源
最近更新 更多