【问题标题】:Child component removing the event listener of socket.io from parent component子组件从父组件中移除socket.io的事件监听器
【发布时间】:2019-04-11 01:18:45
【问题描述】:

我有一个 React 应用程序,我正在将 socket.io 集成到 React 应用程序中。一些需要实时更改的页面,我使用套接字连接到房间,并在更改后将消息发送到该房间。

我有一个子父结构,其中父加入一个房间,而孩子加入一个单独的房间。一切都很完美。当用户断开连接并再次连接时,我在 componentDidMount 上有一个事件,当用户重新连接到 Internet 时将自动加入房间。在 componentWillUnmount 上,我删除了那个事件监听器。但是发生的情况是,当子组件将卸载并重新连接互联网时,应该自动加入父组件房间的父事件不会被调用。似乎 Child componentWillUnmount 也删除了父组件的事件侦听器。请让我知道我该如何解决它以及我做错了什么。

sockets.js

import openSocket from 'socket.io-client';

let socket = '';
if(typeof window !== "undefined") {

    let connectionUri = "http://"+window.location.hostname+":9001"


    socket = openSocket(connectionUri;

    socket.on('messages', function(data) {
        alert(data);
    });
}

export default socket;

我在每个 react 组件中使用上述文件来执行有关套接字的功能。

父.js

import React, {Component} from 'react'
import Child1 from '../Child1/Index'
import Child2 from '../Child2/Index'
import socket from '../../../sockets'


export default class Parent extends Component {

    componentDidMount() {
        socket.emit('joinRoom', 'Parent')
        socket.on('changeStatus', (data) => {
            .....
        })
        socket.on('connect', () => {
            socket.emit('joinRoom', 'Parent')
        })
    }

    componentWillUnmount() {
        socket.emit('leaveRoom', 'Parent')
        socket.off('changeStatus')
        socket.off('connect')
    }

    render() {

            switch(this.props.pageValue) {
                case "Child1":
                    return <Child1 .... />
                case "Child2":
                    return <Child2 .... />
                default:
                    return null
            }
    }

}

child.js

import React, {Component} from 'react'
import socket from '../../../sockets'


export default class Parent extends Component {

    componentDidMount() {
        socket.emit('joinRoom', 'Child')
        socket.on('changeStatus', (data) => {
            .....
        })
        socket.on('connect', () => {
            socket.emit('joinRoom', 'Child')
        })
    }

    componentWillUnmount() {
        socket.emit('leaveRoom', 'Child')
        socket.off('changeStatus')
        socket.off('connect')
    }

    render() {
       ......
    }

}

服务器.js

client.on('joinRoom', function(room) {
    console.log('Connected to Room:', room);
    client.join(room);
});

client.on('leaveRoom', function(room) {
    console.log('Leaving Room:', room);
    client.leave(room);
});

所以当 socket.off('connect') 调用 Child1/Child2 时。似乎 Parent connect 事件监听器也被删除了。

如果你们有任何问题,请告诉我。抱歉英语不好

【问题讨论】:

    标签: javascript reactjs sockets socket.io


    【解决方案1】:

    仅使用事件名称调用 socket.off 会导致它取消订阅该事件的 所有 回调。您需要指定取消订阅哪个回调,以便其他人可以保留。

    componentDidMount() {
      socket.emit('joinRoom', 'Child')
      socket.on('changeStatus', this.onChangeStatus);
      socket.on('connect', this.onConnect);
    }
    
    onChangeStatus(data) {
     ...
    }
    
    onConnect() {
      socket.emit('joinRoom', 'Child')
    }
    
    componentWillUnmount() {
      socket.emit('leaveRoom', 'Child')
      socket.off('changeStatus', this.onChangeStatus);
      socket.off('connect', this.onConnect);
    
      // instead of:
      // socket.off('changeStatus') 
      // socket.off('connect') 
    }
    

    【讨论】:

    • 谢谢。解决了这个问题。之前查看 .off() 的定义,但有点错过了选择器部分。我的坏..再次感谢:)
    猜你喜欢
    • 2015-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-03
    • 1970-01-01
    • 1970-01-01
    • 2021-11-02
    • 1970-01-01
    相关资源
    最近更新 更多