考虑到以下功能组件:

const DataLog: FC = (props) => {
  const [events, setEvents] = useState<string[]>([]);

  const pushEvent = (event: string) => {
    const updatedEvents = [...events];
    updatedEvents.push(event);
    setEvents([...updatedEvents]);
  };

  useEffect(() => {
    const socket: Socket<ServerToClientEvents, ClientToServerEvents> = io(
      'http://localhost:9000'
    );

    socket.on('connect', () => {
      console.log('Web socket connected');
    });

    socket.on('event1', (event: string) => {
      pushEvent(event);
    });

    socket.on('event2', (event: string) => {
      pushEvent(event);
    });
  }, []);

  return (
    <div>
      {events.map((event: string, index: number) => {
        return <div key={index}>{event}</div>;
      })}
    </div>
  );
};

export default DataLog;

每次通过套接字接收到event1event2消息时,我都要更新events状态变量.io websocket连接.如果消息以合理的间隔传入,这可以正常工作,但当event1event2或多条event1event2消息以非常快的速度传入时,问题就会出现.在处理下一个事件之前,状态更新没有足够的时间完成,导致events数组被最后一次调用setEvents覆盖.有没有办法确保每个新消息都被添加到events状态对象中?我需要手动批处理状态更新吗?有没有另一个钩子可以用来保存更新之间的状态?

推荐答案

pushEvent函数是useEffect的依赖项,但不在其依赖项数组中.这意味着更新使用指向原始空数组的初始函数.

您可以将其添加为useEffect()的依赖项:

useEffect(() => {
  // your code
}, [pushEvent]);

然而,这将导致在每次渲染时调用useEffect,因为pushEvent是在渲染时重新创建的,所以您可能应该避免这样做.

const DataLog: FC = (props) => {
  const [events, setEvents] = useState<string[]>([]);

  useEffect(() => {
    const socket: Socket<ServerToClientEvents, ClientToServerEvents> = io(
      'http://localhost:9000'
    );

    socket.on('connect', () => {
      console.log('Web socket connected');
    });

    socket.on('event1', (event: string) => {
      setEvents(prev => [...prev, event]);
    });

    socket.on('event2', (event: string) => {
      setEvents(prev => [...prev, event]);
    });
  }, []);

  return (
    <div>
      {events.map((event: string, index: number) => {
        return <div key={index}>{event}</div>;
      })}
    </div>
  );
};

Reactjs相关问答推荐

无法覆盖MUI工具栏上的左右填充,除非使用!重要

为什么我无法访问窗口事件处理程序中的状态?

props 可以在Reaction中锻造吗?

在Reaction+Redux+RTKQuery中对API调用进行排序

防止在Reaction中卸载

更改购物车中的产品数量后,PayPal Reaction/Next JS按钮未更新

基本react 应用程序正在触发两次Use Effect

在url中使用MongoDB对象ID被认为是不好的做法?

在构建或部署Reaction应用程序时出错

GitHub页面配置

状态更改是否卸载功能组件

ctx.strokeStyle 在 canvas html 5 中不起作用

React js拖放图像并预览

滚动视图样式高度没有任何区别

当从子状态更改复制时,react 父状态更改.我该如何防止这种情况?

无法设置 null 的属性(设置src)

onChange in useEffect 的最佳实践

Suspense/Await - 解析数据加载/保存到状态后无限循环

使用 axios 响应路由 Dom 操作

当状态改变时如何执行一些动作,但只针对第一次更新?