You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Context API实现Socket.io聊天室活跃用户展示的问题

解决Socket.io聊天应用房间用户列表筛选问题

首先修正你代码里的一个小问题:useEffect的依赖数组里不需要加users,否则每次users更新都会重新绑定socket事件,容易导致重复监听。应该只保留socket作为依赖,同时新增组件卸载时的事件清理逻辑,避免内存泄漏。

接下来实现房间用户筛选,有两种常用方式:

方式一:先筛选再遍历(推荐)

先通过filter方法筛选出当前房间的用户,再对筛选后的数组进行map渲染,代码逻辑更清晰易读:

const ChatMembers = ({ socket }) => {
  const currentUser = useContext(AuthContext);
  const [users, setUsers] = useState([]);
  const { room } = useContext(RoomContext);

  useEffect(() => {
    const handleNewUser = (data) => setUsers(data);
    socket.on("newUserResponse", handleNewUser);
    
    // 组件卸载时移除监听
    return () => {
      socket.off("newUserResponse", handleNewUser);
    };
  }, [socket]);

  // 筛选出当前房间的用户
  const currentRoomUsers = users.filter(user => user.room === room);

  return (
    <div>
      {currentRoomUsers.map((user) => (
        <p key={user.socketID}>{user.currentUser.displayName}</p>
      ))}
    </div>
  );
};

方式二:在map中直接加入条件判断

如果想直接在map函数内处理,可通过条件判断决定是否渲染当前用户,不匹配的用户返回null即可:

const ChatMembers = ({ socket }) => {
  const currentUser = useContext(AuthContext);
  const [users, setUsers] = useState([]);
  const { room } = useContext(RoomContext);

  useEffect(() => {
    const handleNewUser = (data) => setUsers(data);
    socket.on("newUserResponse", handleNewUser);
    
    return () => {
      socket.off("newUserResponse", handleNewUser);
    };
  }, [socket]);

  return (
    <div>
      {users.map((user) => {
        // 仅渲染当前房间的用户
        if (user.room !== room) return null;
        return <p key={user.socketID}>{user.currentUser.displayName}</p>;
      })}
    </div>
  );
};

关键说明

  • 以上代码假设Socket.io返回的user对象中包含room字段,且该字段值与RoomContext中的room完全匹配,请根据你的后端实际数据结构调整判断条件。
  • 新增的事件清理逻辑能避免组件卸载后仍残留监听,防止内存泄漏和重复触发问题。

内容的提问来源于stack exchange,提问作者Marquis4484

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 18:12:03