Router: Route has changed event

Created on 18 Apr 2019  路  6Comments  路  Source: reach/router

Have a question?

I work on a Gatsby website ATM and have a Navigation component where I want to call a function (resetMobileNav) when the route has changed.

Is this possible? I expect something like router.on('navigationEnd').then((newRoute, oldRoute) => {...))

needs docs

Most helpful comment

Okay, I have found a way:

  public componentDidMount() {
    globalHistory.listen(({ action }) => {
      if (action === 'PUSH') {
        this.resetNav()
      }
    })
  }

but I'll wait if someone else has a better more modern solution until I close

All 6 comments

Okay, I have found a way:

  public componentDidMount() {
    globalHistory.listen(({ action }) => {
      if (action === 'PUSH') {
        this.resetNav()
      }
    })
  }

but I'll wait if someone else has a better more modern solution until I close

Thanks man, saved my life. This should be documented. A Google search on '"reach-router" route change event' leads just here though.

Huge thanks as well. Searched for a long time. This should definitely be documented!

Note that you should call the unsubscriber returned from .listen():

componentDidMount() {
  this.historyUnsubscribe = globalHistory.listen(...);
}
componentWillUnmount() {
  this.historyUnsubscribe();
}

or with hooks:

```js
useEffect(() => {
return globalHistory.listen(...);
}, []);

import { globalHistory } from '@reach/router' for those wondering where this globalHistory is coming from (took me 5 minutes to figure it out)

Is there any way to detect route change before it actually changes?

Here globalHistory.listen() actually triggers after the route has changed

Is there any way to detect route change before it actually changes?

Here globalHistory.listen() actually triggers after the route has changed

Hello so I've done something to work around this problem. As of now, there's no available event when a user is ABOUT to change routes. So what I did is, I made a custom event and made a wrapper function for navigate. The purpose of the wrapper function is to call my custom event before the actual call for navigate. It looks like this

let beforePathChange = new Event("onpathchange", {cancelable: true});

export async function navigateTo(path: string, options?: NavigateOptions<{}>) {
  let canceled = dispatchEvent(beforePathChange);
  if(!canceled) {
    await navigate(path, options);
  }
}

I exported it so that I can use it to any other classes. In the recieving end, it looks like this

componentDidMount() {
        window.history.pushState(null, document.title, window.location.href);

        window.addEventListener("onpathchange", this.onPathChangeHandler);
}

componentWillUnmount() {
        window.removeEventListener("onpathchange", this.onPathChangeHandler);
}

And finally in onPathChangeHandler method

onPathChangeHandler(e: any) {
    if(window.confirm(alertMessage)) {
         e.preventDefault();
    } else {
     window.history.pushState(null, document.title, window.location.href);  
    }
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

thupi picture thupi  路  4Comments

MarioKrstevski picture MarioKrstevski  路  3Comments

sseppola picture sseppola  路  4Comments

danoc picture danoc  路  3Comments

michaelwiktorek picture michaelwiktorek  路  4Comments