我有一个类似这样的Reaction组件,我在其中设置了一个WebSocket,并在WebSocket事件上try 在Redux内部更新状态

const Body = () => {
    // Hook for Redux dispatch
    const dispatch = useDispatch();

    // REDUX reducers
    const workCenterAvailabilityQueue = useSelector(selectAllWorkCenterAvailabilities)

    // Add or Update workCenterAvailability
    let existingWorkCenter;
    const workCenterAvailabilityHandler = (id, data) => {
        console.log('id = ', id)
        console.log('data = ', data)
        console.log(workCenterAvailabilityQueue)

        existingWorkCenter = workCenterAvailabilityQueue.find(bm => bm.WorkCenter.WorkCenter_ID === id);
        console.log(existingWorkCenter)

        if (existingWorkCenter) {
            console.log('WorkCenter exists, updating data!')
            dispatch(updateWorkCenterAvailability({
                id: existingWorkCenter.id,
                changes: { Connection_Status: data.Connection_Status }})
            );
        }
        else {
            console.log('WorkCenter does not exist, creating one!')
            dispatch(addWorkCenterAvailability(data));

        }
    }

    // Debugging
    useEffect(() => {
        console.log('Updated state:', workCenterAvailabilityQueue);
        if(workCenterAvailabilityQueue[10]){
            console.log('workCenterAvailabilityQueue[10] -> ', workCenterAvailabilityQueue[10])
        }
        console.log('\n')
    }, [workCenterAvailabilityQueue]);

    // Web Socket setup
    useEffect(() => {
        console.log('connecting to Flask socket')
        const socket = io('http://localhost:5000');

        console.log('Start listening')
        socket.on('workCenterAvailability', (data) => {
            workCenterAvailabilityHandler(data.WorkCenter.WorkCenter_ID, data)
        });

        console.log('emitting message')
        socket.emit('requestWorkCenterAvailability');
        console.log('emitted!')

        // Clean up function
        return () => {
            socket.disconnect();
        };
    }, []);

所以我的问题是,当我try 使用处理程序函数时,workCenterAvailabilityQueue总是作为空数组返回,所以当我试图在队列中查找对象时,它总是失败

但是,基于位于调试目的底部的useEffect挂钩,我可以看到,每次向队列添加内容时,实际上都会将其添加到Redux

为什么我的workCenterAvailabilityQueue不包含实时信息?

推荐答案

第二个useEffect钩子在"workCenterAvailability"事件回调处理程序中调用workCenterAvailabilityHandler,该处理程序在所选的workCenterAvailabilityQueue状态上具有陈旧的Java脚本闭包.

您可以通过几种方式解决此问题:

  1. 导入Store对象并获取workCenterAvailabilityHandler回调处理程序中的当前状态值.

    import store from '../path/to/store';
    
    ...
    
    // Add or Update workCenterAvailability
    const workCenterAvailabilityHandler = (id, data) => {
      const state = store.getState();
      const const workCenterAvailabilityQueue = 
        selectAllWorkCenterAvailabilities(state);
    
      const existingWorkCenter = workCenterAvailabilityQueue.find(
        bm => bm.WorkCenter.WorkCenter_ID === id
      );
    
      if (existingWorkCenter) {
        dispatch(updateWorkCenterAvailability({
          id: existingWorkCenter.id,
          changes: { Connection_Status: data.Connection_Status }
        }));
      } else {
        dispatch(addWorkCenterAvailability(data));
      }
    };
    
    ...
    
    // Web Socket setup
    useEffect(() => {
      const socket = io('http://localhost:5000');
    
      socket.on('workCenterAvailability', (data) => {
        workCenterAvailabilityHandler(data.WorkCenter.WorkCenter_ID, data)
      });
    
      socket.emit('requestWorkCenterAvailability');
    
      // Clean up function
      return () => {
        socket.disconnect();
      };
    }, []);
    
    ...
    
  2. 使用Reaction引用缓存当前的workCenterAvailabilityQueue状态值.

    ...
    
    const workCenterAvailabilityQueue = useSelector(
      selectAllWorkCenterAvailabilities
    );
    
    const workCenterAvailabilityQueueRef = React.useRef();
    
    useEffect(() => {
      workCenterAvailabilityQueueRef.current = workCenterAvailabilityQueue;
    }, [workCenterAvailabilityQueue]);
    
    ...
    
        // Add or Update workCenterAvailability
    const workCenterAvailabilityHandler = (id, data) => {
      const const workCenterAvailabilityQueue = 
        workCenterAvailabilityQueueRef.current;
    
      const existingWorkCenter = workCenterAvailabilityQueue.find(
        bm => bm.WorkCenter.WorkCenter_ID === id
      );
    
      if (existingWorkCenter) {
        dispatch(updateWorkCenterAvailability({
          id: existingWorkCenter.id,
          changes: { Connection_Status: data.Connection_Status }
        }));
      } else {
        dispatch(addWorkCenterAvailability(data));
      }
    };
    
    // Web Socket setup
    useEffect(() => {
      const socket = io('http://localhost:5000');
    
      socket.on('workCenterAvailability', (data) => {
        workCenterAvailabilityHandler(data.WorkCenter.WorkCenter_ID, data)
      });
    
      socket.emit('requestWorkCenterAvailability');
    
      // Clean up function
      return () => {
        socket.disconnect();
      };
    }, []);
    
    ...
    

Javascript相关问答推荐

promise .all()永不解决

我的JS代码将按照哪个序列被解释

JavaScript Date对象在UTC中设置为午夜时显示不正确的日期

如何解决(不忽略)reaction详尽的linter规则,而不会在获取数据时导致无限的reender循环

如何使用Paged.js仅渲染特定页面

通过实现regex逻辑自定义数据表搜索

如何将连续的十六进制字符串拆分为以空间分隔的十六进制块,每个十六进制块包含32个二元组?

类型自定义lazy Promise. all

如何解决chrome—extension代码中的错误,它会实时覆盖google—meet的面部图像?'

Angular:动画不启动

单击ImageListItemBar的IconButton后,在Material—UI对话框中显示图像

如何解决useState错误—setSelect Image不是函数''

如何在ASP.NET JavaScript中使用Google Charts API仅对绘制为负方向的条形图移动堆叠条形图标签位置

覆盖加载器页面避免对页面上的元素进行操作

如何在箭头函数中引入or子句?

Puppeteer上每页的useProxy返回的不是函数/构造函数

为什么我的按钮没有从&q;1更改为&q;X&q;?

使用类型:assets资源 /资源&时,webpack的配置对象&无效

在查看网页时,如何使HTML中的按钮工作方式类似于鼠标上的滚轮或箭头键?

React:防止useContext重新渲染整个应用程序或在组件之间共享数据而不重新渲染所有组件