React - closure issue with a callback

Viewed 294

i've been having some issues with what im guessing is closure and i am only guessing because it looks like i don't understand it as well as i thought. Here is the issue:

I am trying to establish a web socket connection using Stomp. The way it works is, you create a stomp client

let stompClient = Stomp.over(socket);

and then you subscribe to some routes, passing in the route and passing in a callback that gets called when that route is hit

stompClient.subscribe("/topic/some-route",(message) => myCallback(message))

Since creating a client seems like a one time thing, i decided to put it in a useEffect hook with no dependencies in the array, so that the client only gets created when the component mounts.

useEffect(() => {
//some unimportant setup

let stompClient = Stomp.over(socket);

stompClient.subscribe("/topic/some-route",(message) => myCallback(message))

}, [])

I also keep some state in my component, to keep it simple, lets say i keep this:

const [counter, setCounter] = useState(0);

And what i want my callback to do, is just print out the state, so:

const myCallback = (message /* the message variable is unimportant here */ ) => {
console.log(counter);
}

Now, as the user is using the app, the counter state is going to change, but whenever the callback gets triggered, it always prints 0. Using the knowledge of closure i have, i am guessing that...: (this is question #1)

  1. Because the function closure (the word context seems more fitting for me) gets initialised when the function is created, the function takes the counter variable as a 0, and that is the reason it always prints 0. Is this statement correct?

If i move the stompClient.subscribe("/topic/some-route",(message) => myCallback(message)) outside of the useEffect hook, the myCallback function will print out the current state, however, considering that this .subscribe(...) function creates a whole new subscription towards my stomp broker, i would end up with hundreds of subscriptions, one for each state update i have, which is obviously not a solution. Which leads me to question #2,

  1. Considering i need to call this .subscribe(message, callback) function only once, how can i pass in a callback that will reflect my state?

Thank you!

1 Answers

Have you tried calling a function from your callback and then logging the state from that function ?

const myCallBack = (message) => {
  onMessageReceived();
}

const onMessageReceived = () => {
  console.log(counter);
}

Maybe?

Related