2

I have a page that connects to a SockJS socket over stomp. But when pass a function that is supposed to change the state to the .subscribe callback it doesn't change the page's state (the rest of the function completes normally) Here is the code:

export default function HomePage() {

    ...some other states...

    const [isIncomingCall, setIsIncomingCall] = useState(false)

    function initSocket() {
        const socket = new SockJS(`${process.env.API_URL}/ws`);
        const stompClient = over(socket);
        stompClient.connect(
            {},
            () => onSocketConnected(stompClient),
            onSocketError
        )
        appContext.setSocket(stompClient)
    }

    function handleIncomingCall(data) {
        const state = JSON.parse(data.body.toLowerCase());
        setIsIncomingCall(state)
    }

    function onSocketConnected(stompClient) {
        const options = {
            accessToken: cookies['logged-in'],
        };

        stompClient.send("/app/connect", {}, JSON.stringify(options));
        stompClient.subscribe(`/user/search/complete`, handleSearchComplete)
        stompClient.subscribe(`/user/search/failed`, handleSearchError)
        stompClient.subscribe(`/user/call/incoming`, handleIncomingCall)
    }

    useEffect(() => {
        if (!appContext.socket && cookies['logged-in']) {
            initSocket()
        }
    }, [])

    return (
        <>
            <AnimatePresence>
                {
                    isIncomingCall && <CallModal
                        onAccept={acceptIncomingCall}
                        onReject={rejectIncomingCall}
                    />
                }
            </AnimatePresence>
            ...other page code...
        </>
    )
}

The initSocket function is called on page render inside the useEffect. I have tried wrapping the callback with a useCallback and binding it to the page and calling setIsIncomingCall inside an arrow function, but it didn't seem to help.

Nikitorius
  • 49
  • 6
  • yes, it is inside the page component – Nikitorius Jul 11 '22 at 14:05
  • Please post the `useEffect` which calls `initSocket`. – Nice Books Jul 11 '22 at 14:08
  • updated the post with the useEffect – Nikitorius Jul 11 '22 at 14:13
  • Is `handleIncomingCall` getting called ? – Nice Books Jul 11 '22 at 17:34
  • It is definitely being called, i can print out the data received from the socket event in it, but ```setIsIncomingCall``` is not executed for some reason, because ```useEffect``` depending on ```isIncomingCall``` state doesn't get triggered. Out of everything that I've found on similar issues it could be because of wrong ```this``` object inside the callback, even though i don't call ```this``` myself. – Nikitorius Jul 11 '22 at 22:50
  • There's no reason why `handleIncomingCall` is executed but `setIsIncomingCall` is not. What is the value of `state` inside `handleIncomingCall` ? Is it a falsy value ? – Nice Books Jul 12 '22 at 08:14
  • The value of ```state``` is always either ```true``` or ```false``` – Nikitorius Jul 12 '22 at 08:29
  • As I've said before, the ```handleIncomingCall``` is being executed correctly, and i can see when a ```true``` value is supposed to be passed into ```setIsIncomingCall```, but it just doesn't set the state. – Nikitorius Jul 12 '22 at 09:29
  • My guess: `setIsIncomingCall` is setting the state correctly & `isIncomingCall` is indeed updated. But it's not reflected in the render due to some problem in the ``. Try rendering the value of `isIncomingCall` inside a `

    ` to be sure.

    – Nice Books Jul 12 '22 at 09:50
  • Sadly, it is not the `````` 's fault, the state is just not being set for some reason – Nikitorius Jul 13 '22 at 09:26
  • @NiceBooks I am facing the same issue, in the callback functions I can't set any state....the callback functions are indeed invoked but they don't allow to set the state. – Neeraj Jain Nov 29 '22 at 17:50
  • @NeerajJain, try adding your state into a context if you are trying to change the state across multiple pages. This fixed the issue for me, read my answer for my understanding of the problem. – Nikitorius Nov 30 '22 at 18:15

1 Answers1

0

Ok, so the problem was: Callbacks were initialized on first visiting the HomePage, but for user to set that they can receive calls, they needed to go to the ProfilePage and flip the switcher. In the process of going back and forth between the pages React loses the pointer to the original isIncomingCall state and sets it on the previous version of the HomePage it seems.

Nikitorius
  • 49
  • 6