【问题标题】:Socket.io - React: How to display the users connected in a room?Socket.io - React:如何显示房间中连接的用户?
【发布时间】:2021-04-20 22:32:51
【问题描述】:

我正在尝试映射连接到我的聊天应用程序的用户并将它们呈现在一个 div 中。

我将用户保存在对象数组中,并在用户从后端的聊天室连接和断开连接并在前端获取对象时发出更新数组的事件,将其保存在数组中并使用地图显示用户。

当我映射数组以显示用户时,我的页面只显示当前用户和后续用户,而不显示之前连接的用户。例如,如果我打开名为“Bruce”的应用程序和另一个用户为“Andrew”的页面,则第一页将显示两个用户,第二个页面将显示“Andrew”。如果我 console.log 我从后端获取的数组,它会显示两个用户。如果我退出任何页面或重新加载它,它会显示“TypeError: Cannot read property 'username' of undefined”

后端

const users = []

    // Storing user
    const user = { id, username, room } 
    users.push(user)

const getUsersInRoom = (room) => {
    return users.filter((user) => user.room === room)
}

socket.on('join', ({ username, room }, callback) => {
    io.to(user.room).emit('roomData', {
      room: user.room,
      users: getUsersInRoom(user.room)
    })
    callback()
  })

  socket.on('disconnect', () => {
      io.to(user.room).emit('roomData', {
        room: user.room,
        users: getUsersInRoom(user.room)
      })
    }
  })

前端

    const [usersName, setUsersName] = useState([]);

    useEffect(() => {
        socket.on('roomData', ({room, users}) => {
            setUsersName(previousUsersName => [...previousUsersName, users]);
        })
    },[]);

    return (
             <div>
                {
                    usersName.map((name, i) => (
                        <div key={i}>
                            <p>
                                <span>{name[i].username}</span>
                            </p>
                        </div>
                    ))
                }
              <div/>

当我 console.log(usersName) 它以这种格式显示数组:

[Array(1)]
   0: Array(1)
      0:
         id: "yXXo7TXVHWN1bzl6AAAV"
         room: "Games"
         username: "Bruce"

我相信后端是正确的,因为我得到了所有用户。我认为的问题是我如何使用“name [i] .username”映射数组,因为当我重新加载页面时它会破坏它并且页面会错误地呈现名称,如上所述。

感谢您的任何帮助,如果您感到困惑或遗漏了一些数据,请告诉我。

【问题讨论】:

    标签: javascript node.js arrays reactjs socket.io


    【解决方案1】:

    这是我使用“name[i].username”在地图中显示名称的方式。

    我猜是因为索引正在更新并破坏应用程序,当新用户进入页面时,它不会显示前任,因为索引指向新用户。

    我通过映射包含我在后端接收的对象数组的第一个数组并映射对象数组本身以显示名称来让它工作。

    我在状态下保存数组的方式也是错误的。由于我接收到所有连接的用户,因此无需使用以前的用户填充数组,然后添加新用户。

    这里是变化

        const [usersName, setUsersName] = useState([]);
    
            socket.on('roomData', ({room, users}) => {
                setUsersName([users]);
            })
    
    
            {
                usersName.map((name,index) => 
                    <div key={index}>
                        {
                            name.map((username, subindex) =>
                                <p key={subindex}>{username.username}</p>
                            )
                        }
                    </div>
                )
            }
    

    【讨论】:

      猜你喜欢
      • 2020-08-18
      • 2020-02-24
      • 2018-01-09
      • 1970-01-01
      • 2020-07-30
      • 2017-03-21
      • 2020-11-23
      • 2015-01-05
      • 1970-01-01
      相关资源
      最近更新 更多