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.
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.