在 useEffect 之外访问我的套接字变量

wei*_*wei 2 sockets socket.io reactjs 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)
  }
}
Run Code Online (Sandbox Code Playgroud)

我尝试在导入下声明我的套接字,如下所示:

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

export default function Chat() {
...
}
Run Code Online (Sandbox Code Playgroud)

然而,这种方式的问题是 socket.disconnect() useEffect 钩子内部不再起作用,并且套接字连接保持活动状态。

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

export default function Chat() {
  const socket = io (endpoint + '/chat')
   ...
}
Run Code Online (Sandbox Code Playgroud)

但这会导致多个套接字连接触发,并且我最终会出现内存泄漏以及服务器上的许多套接字连接,这些连接无法全部用 socket.disconnect() 关闭

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

Tra*_*mes 6

只需为您的套接字实例添加状态并将其设置在 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)
  }
}
Run Code Online (Sandbox Code Playgroud)

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