基于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
相关产品推荐
相关产品推荐

