Redux的usefoot钩子总是返回一个空数组

vlurs2pr  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(175)

我有一个像这样的react组件,在这里我设置了一个WebSocket,在WebSocket事件中,我试图更新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();
        };
    }, []);

字符串
所以我的问题是,当我尝试使用处理函数时,workCenterAvailabilityQueue总是作为一个空数组返回,所以当我尝试在队列中查找对象时,它总是失败
然而,基于我一直放在底部用于调试目的的useEffect钩子,我可以看到每次我向队列添加东西时,它实际上都被添加到Redux中
为什么我的workCenterAvailabilityQueue不包含实时信息?

mo49yndu

mo49yndu1#

第二个useEffect钩子在"workCenterAvailability"事件回调处理程序中调用workCenterAvailabilityHandler,该事件回调处理程序在选定的workCenterAvailabilityQueue状态上具有过时的JavaScript闭包。
您可以通过以下几种方式解决此问题:
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();
  };
}, []);

...

字符串
1.使用React ref缓存当前的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();
  };
}, []);

...

相关问题