Search code examples
javascriptreactjsreact-nativeuse-effectuse-state

How to get current value of useState in useEffect without re-running?


I need to initiate a function only once, which fires WebSocket events whenever new objects are created on backend.

I try to store these added objects in a state array using useState.

But every time a new object is created, the last added values are not found, it is always a fresh array. How can I get the current value of the state notifs without running the function again every time it is changed?

    const [notifs, setNotifs] = useState([])

    useEffect(() => {

        const subscribe = () => {
            //Socket subscription : When new object is created
            let subs = new SocketSubscription();
            subs('create', (object) => {
                let newNot = Notification.initFromPFObject(object)
                alert("Notification : " + newNot.message)

                //PROBLEM: NOTIFS here are always a blank array [] 
                let ntt = [...notifs]
                ntt.unshift(newNot)
                setNotifs(ntt)
            });
        }

        subscribe()

    }, [])

Solution

  • Instead of passing new value to setNotifs you can pass a function which receives currentValue as first parameter and you can update it as:

    setNotifs((curr) => [newNot, ...curr]);
    

    AFAIT the main reason is that you are close over notifs which has [] array. When then callback to subs called then it takes the stale value not the current value. So you can pass function to setNotifs which automatically recieves current value as first pararmeter.