在useEffect

时间:2019-09-06 23:56:22

标签: reactjs sockets socket.io react-hooks

我正在将socket.io用于多个聊天室,并且希望我的套接字连接仅在聊天室打开时才存在,而在卸载聊天室时才关闭。当前,我在useEffect挂钩中连接到套接字。问题是,我无法在任何函数中执行socket.emit(),因为我的套接字是在useEffect中定义的,如下所示:

import io from 'socket.io-client'

export default function Chat() {
  useEffect(() => {
    const socket = io(endpoint + '/chat')
    return () => { socket.disconnect() }
  }

  const sendMessage = (msg) => {
    // Cant access this because socket is defined in useEffect!
    socket.emit('message', msg)
  }
}

我已经尝试过在我的导入下声明我的套接字,就像这样:

import io from 'socket.io-client'
const socket = io(endpoint + '/chat')

export default function Chat() {
...
}

但是,这种方式的问题是 socket.disconnect() 在useEffect挂钩中不再起作用,并且套接字连接保持活动状态。

我还尝试过将套接字声明为函数的变量,如下所示:

export default function Chat() {
  const socket = io (endpoint + '/chat')
   ...
}

但这会导致多个套接字连接被触发,最终导致内存泄漏以及服务器上很多套接字连接,而这些套接字连接无法全部用socket.disconnect()关闭

任何帮助将不胜感激,谢谢

1 个答案:

答案 0 :(得分:1)

只需为您的套接字实例添加状态并将其设置在您的useEffect挂钩中

import io from 'socket.io-client'

export default function Chat() {

   const [currentSocket, setCurrentSocket] = useState(null)

  useEffect(() => {
    const socket = io(endpoint + '/chat')
    setCurrentSocket(socket)
    return () => { socket.disconnect() }
  }

  const sendMessage = (msg) => {
    // Access the socket
    currentSocket.emit('message', msg)
  }
}

现在您可以从currentSocket状态变量访问套接字