'Unable to access state - React.js working with Websocket

This is my first post here, so nice to meet you all. I have recently started my adventure with React, so my question probably will not be very challenging (it could also be very basic stuff), however I got stuck with this problem for a while.

So I am working with WebSocket that when connected, sends one-time message with all products currently in stock. Then, every few seconds, it sends object with update of product stock changes.

I managed to update state with first recieved message, but then, when I try to access state in a function handleData, state is empty array. This is happening despite the fact that the data rendered on the page using state is still visible, state is visible in Firefox Developer Edition React DevTools, and the useEffect that is associated with the state change fires only once - at the start, so it doesn't change.

I want to be able to access data I put before in state, in function handleData, so that I can update the state with stock changes. It is interesting that when the websocket loads again, the "products" status variable is extended by the previous, unloaded products.

Here is code of my component:

import React, { useState, useEffect, useRef } from 'react';
import Product from './Product';

export default function ProductsList() {
    const [products, setProducts] = useState([]);
    const ws = useRef(null);

    useEffect(() => {
        ws.current = new WebSocket(<HERE IS WEBSOCKET URL BUT I CENSORED IT>);
        ws.current.onmessage = (message) => handleData(message);
        return () => ws.current.close();
    },[]);

    useEffect(() => {
        console.log("Products useEffect:", products)
    }, [products]) //prints fine here

    const handleData = (message) => {
        const data = JSON.parse(message.data);

        switch (data.operation) {
            case 'product.stock.decreased': {
                console.log("Products Switch:", products) // prints empty array here
                break;
            }
            default: {
                setProducts(prevState => [...prevState, ...data]) // here state updates
                break;
            }
        }
    }
    return (
        <div className="ProductsList">
            {products.map(p => <Product key={p.productId} productId={p.productId} name={p.name} price={p.price} stock={p.stock} />)}
        </div>
    );
}

Many thanks in advance for your help.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source