React. Функция не видит изменение state

Дефолтное значение стейта orders - { orders: [] }

Каждую секунду я через сокет отправляю запрос на получение новых заказов, данные передаются в функцию setOrdersListner, которая должна сравнивать длину массива orders.orders и длину массива response.orders для обнаружения новых заказов, по факту в функциях setOrdersListner и колбэке checkLength стейт orders всегда равен значению инициализации { orders: [] }, из-за чего checkLength всегда возвращает True, что является некорректным поведением.

Далее по приложению стейт orders считывается корректно, значит setOrders в функции setOrdersListner работает корректно. React DevTools так же подтверждает что orders изменяется.

Прошу у Вас помощи в решении проблемы.

React DevTools введите сюда описание изображения

Консоль ( слева response, справа orders)

введите сюда описание изображения

Код

const [orders, setOrders] = useState({orders: []});

const checkLength = useCallback((response) => response.orders.length > orders.orders.length, [orders]);

const setOrdersListner = (response) => {
    if (checkLength(response)){
        setOrders(response);
        console.log(response, orders);
    }
  };

useEffect(() => {
    socket.on("sendingNotCompleted", setOrdersListner);
}, [])

useEffect(() => {
    const interval = setInterval( () => {
        if (socket){
            socket.emit('fetchNotCompleted')
        }
    }, 1000)
    return () => clearInterval(interval);
  }, []);

Ответы (1 шт):

Автор решения: Finskiy

Проблема заключалось в том, как я понял, при первой отрисовке в socket.emit передавалась функция, знающая только текущее состояние стейта. Решено добавлением очистки в useEffect и добавлением депса для обновления.

const setOrdersListner = (response) => {
        if (checkLength(response)){
            console.log(response, orders);
            setOrders(response);
        }
      };
    
    useEffect(() => {
        socket.on("sendingNotCompleted", setOrdersListner);

        return function cleanup (){
            socket.removeAllListeners('sendingNotCompleted');
            console.log('listners cleanup')
        }
    }, [orders])
→ Ссылка