首页 > 解决方案 > 带有 mern 堆栈的 socket.io 无法对未安装的组件执行 React 状态更新

问题描述

大家好,我正在尝试使用在线/离线系统:

后端:

var userCount = 0;
var onlineuserList = [];

io.sockets.on('connection', function (socket) {
  userCount++;
  io.sockets.emit('userCount', { userCount: userCount });

  socket.on('login', function (data) {
    onlineuserList = onlineuserList.filter(user=> user !== data);
    onlineuserList.push(data);

    setInterval(function(){
      io.sockets.emit('onlineuserList', onlineuserList); 
    }, 1000);
  });

  socket.on('logout', function (data) {
      onlineuserList = onlineuserList.filter(user=> user !== data)
      io.sockets.emit('onlineuserList', { onlineuserList: onlineuserList });
  });

  socket.on('disconnect', function() {
    userCount--;
    io.sockets.emit('userCount', { userCount: userCount });
  });
});

前端:

  useEffect(() => {
    socket.on('onlineuserList', (onlineuserList) => {
        if(onlineuserList.length > 0){
          onlinesetuserList(onlineuserList && onlineuserList);
          setStatus(onlineuserList && onlineuserList.includes(props.id));
        } else {
          onlinesetuserList([]);
          setStatus(false);
        }
    });

    return () => socket.off('onlineuserList', onlineuserList);
  }, []);

一切正常,但在控制台日志中我收到此错误:警告:无法对未安装的组件执行 React 状态更新。这是一个空操作,但它表明您的应用程序中存在内存泄漏。要解决此问题,请在 useEffect 清理函数中取消所有订阅和异步任务。

还有一个问题是在后端每秒设置 setinterval 是否安全?

标签: node.jsreactjssocket.io

解决方案


我认为问题在于您没有为 socket.off 方法提供原始回调函数,因此套接字侦听器不会在组件卸载时被清理。

我建议进行以下修复:

useEffect(() => {
    const onlineUserListHandler = (onlineuserList) => {
        if(onlineuserList.length > 0){
            onlinesetuserList(onlineuserList && onlineuserList);
            setStatus(onlineuserList && onlineuserList.includes(props.id));
        } else {
            onlinesetuserList([]);
            setStatus(false);
        }
    }

    socket.on('onlineuserList', onlineUserListHandler);

    return () => socket.off('onlineuserList', onlineUserListHandler);
}, []);

推荐阅读