【问题标题】:connection event gets triggered infinite times for one client in socket.iosocket.io 中的一个客户端的连接事件被无限次触发
【发布时间】:2020-05-15 05:24:36
【问题描述】:

我正在使用带有 nextJS 的 socket.io。在服务器中,我正在监听“连接”事件。 现在,当我启动客户端站点时,服务器中的连接事件会触发无限组。

//客户端中的pages/index.js

import Head from 'next/head'
import { useState, useEffect } from 'react'
import io from 'socket.io-client'

export default function Home() {
  const [ users, setUsers ] = useState(0);
  const socket = io();

  useEffect(() => {
    socket.on('user', (count) => {
     console.log(count)
     setUsers(count)
    })

    return () => {
      socket.disconnect();
    }
  }, [])

  return (
    <div className="container">
      <Head>
        <title>Create Next App</title>
        <link rel="icon" href="/favicon.ico" />
      </Head>
      <p>Online Users: {users}</p>
    </div>
  )
} 

//基于类

class Index extends React.Component {


state = {
    users: 0,
    roomList: []
  }

  componentDidMount(){
    this.socket = io();
    this.socket.on('user', count => {
      this.setState({users: count})
    })

    this.socket.on('roomList', rooms => {
      this.setState({roomList: rooms})
    })
  }

  componentWillUnmount(){
    console.log('unmounted')
    this.socket.disconnect();
  }

  render(){
    return(
      <div>
        <p>Online Users: {this.state.users}</p>
        <div>
          { this.roomList && this.roomList.length !== 0 && 
              this.roomList.map(room => (
                <li key={room}>{room}</li>
              ))
          }
        </div>
      </div>
    )
  }
}

export default Index;

谁能帮我弄清楚为什么它不适用于功能组件?

【问题讨论】:

  • 请将代码贴在您使用的地方Home
  • @VivekDoshi 在文件夹下的 next.js 文件中,Pages 充当单独的页面。并且名为“index.js”的文件充当根页面“/”。希望你明白我的意思。

标签: reactjs socket.io next.js


【解决方案1】:

您是直接在渲染中创建套接字,这意味着每次您的功能组件重新渲染时都会创建一个新的套接字实例。

你必须使用useRef来存储一个socket实例并在useEffect中创建

export default function Home() {
  const [ users, setUsers ] = useState(0);
  const socketInstance = useRef(null);

  useEffect(() => {
    const socket = io();
    socketInstance.current = socket;
    socket.on('user', (count) => {
     console.log(count)
     setUsers(count)
    })

    return () => {
      socket.disconnect();
    }
  }, [])

  return (
    <div className="container">
      <Head>
        <title>Create Next App</title>
        <link rel="icon" href="/favicon.ico" />
      </Head>
      <p>Online Users: {users}</p>
    </div>
  )
} 

【讨论】:

  • 你确定你的 useEffect 有一个空依赖吗?
  • 是的。这两种情况我都试过了。我的服务器配置呢?没事吧?
  • 这对我来说似乎没问题,你确定你不要在其他地方创建套接字实例,而是用 useRef 替换它
  • 基于类的解决方案有效。但是钩子有什么问题呢?
  • 完成!旁边的套接字实例也很有用。我可以将它作为道具发送给其他组件。
猜你喜欢
  • 1970-01-01
  • 2012-06-23
  • 1970-01-01
  • 2021-01-13
  • 1970-01-01
  • 2023-03-26
  • 2021-07-24
  • 2013-09-26
  • 2021-12-10
相关资源
最近更新 更多