title: useLocation changes in the parent useEffect function scope but nested functions use older value
body: <p>There is a custom hook</p>
  
  <pre><code>const useStompSubscription = () =&gt; {
    const dispatch = useDispatch();
    const routerLocation = useLocation();
    const namespace = useSelector(bootstrapNamespaceSelector);
    console.log("routerLocation", routerLocation); // logs correctly when routerLocation changes
    useEffect(() =&gt; {
      console.log("useEffect", routerLocation); // logs correctly when routerLocation changes
      if (!namespace) {
        return;
      }
  
      const stompClient = getSTOMPClient(
        namespace,
        function(message) {
          console.log("onReceiveQueueMessage", routerLocation); // logs only the first route where initialization happened
          if (
            routerLocation.pathname !== QUEUE_PATH &amp;&amp;
            routerLocation.pathname !== WORKLOAD_PATH
          )
            return;
  
          let payload = JSON.parse(message.body);
          if (payload.status === PRINTED || payload.status === CANCELLED) {
            dispatch(onDeletePrintingQueueAction(payload));
          } else {
            dispatch(onCreateOrUpdatePrintingQueueAction(payload));
          }
        },
        function(message) {
          console.log("onReceiveManifestMessage", routerLocation); // logs only the first route where initialization happened
  
          if (routerLocation.pathname !== DELIVERY_MANIFEST_PATH) return;
  
          let payload = JSON.parse(message.body);
          dispatch(onCreateOrUpdateDeliveryPackageAction(payload));
        },
      );
  
      stompClient.activate();
  
      return () =&gt; {
        stompClient.deactivate();
      };
    }, [dispatch, namespace, routerLocation, routerLocation.pathname]);
  };
  </code></pre>
  
  <p>It calls <code>getSTOMPClient</code> function, passing 2 callbacks - <code>onReceiveQueueMessage</code> and <code>onReceiveManifestMessage</code>, which access the <code>routerLocation</code> from the parent scope.</p>
  
  <pre><code>let instance;
  
  export const getSTOMPClient = (
    namespace,
    onReceiveQueueMessage,
    onReceiveManifestMessage,
  ) =&gt; {
    if (isNil(instance)) {
      let host;
      let url;
      if (window.location.port === "") {
        host = `${window.location.hostname}`;
      } else {
        host = `${window.location.hostname}:${window.location.port}`;
      }
      if (window.location.protocol === "https:") {
        url = `wss://${host}/ws`;
      } else {
        url = `ws://${host}/ws`;
      }
  
      instance = new Client({
        brokerURL: url,
        onConnect() {
          const queueTopic = `/ui/${namespace}/queue`;
          this.queueSubscription = this.subscribe(
            queueTopic,
            onReceiveQueueMessage,
          );
  
          const dmTopic = `/ui/${namespace}/dm`;
          this.dmSubscription = this.subscribe(dmTopic, onReceiveManifestMessage);
        },
  
        onDisconnect() {
          const defaultSub = { unsubscribe: noop };
          const queueSubscription = defaultTo(this.queueSubscription, defaultSub);
          const dmSubscription = defaultTo(this.dmSubscription, defaultSub);
          queueSubscription.unsubscribe();
          dmSubscription.unsubscribe();
        },
        // Helps during debugging, remove in production
        debug: str =&gt; {
          console.log(new Date(), str);
        },
      });
    }
  
    return instance;
  };
  </code></pre>
  
  <p>What I expect is that whenever the callbacks are fired they will access the <code>routerLocation</code> from <code>useStompSubscription</code> scope. </p>
  
  <p>The <code>console.log("routerLocation", routerLocation);</code> and <code>console.log("useEffect", routerLocation);</code> log correctly the changes. </p>
  
  <p>However in the callbacks always the first <code>routerLocation</code> is used, the changes doesn't seem to affect it.</p>
  
  <p>This seems to be simple closure.
  What am I missing in here?</p>