Listening for route change with IonReactRouter

So currently I am trying to hook into route change so I can conditionally render ionic tabs based on the page. It seems simple, has been all but achievable at the moment.

From what I understand the IonReactRouter Simply encapsulates the BrowserRouter Component from React. Which lead me to believe that I could use the generic events that are exposed on the normal BrowserRouter. For instance, I attempted to hook into the route changing with the onChange prop.

The code Went something like this:

const App: React.FC = () => {
  var renderNav = false;

  const routeChange = () => {
    console.log(window.location.pathname);
  };

  return (
    <IonApp>
      <IonReactRouter onChange={routeChange}>
        <IonTabs>
          <IonRouterOutlet>
            <Route path="/tab1" component={Tab1} exact={true} />
            <Route path="/tab2" component={Tab2} exact={true} />
            <Route path="/tab3" component={Tab3} exact={true} />
            <Route path="/deal/:id" component={DealPage} />
            <Route path="/login" component={LoginPage} />
            <Route path="/signup" component={SignUpPage} />
            <Route
              path="/"
              render={() => <Redirect to="/login" />}
              exact={true}
            />
          </IonRouterOutlet>

// Conditionally render this.
{renderNav && (
            <IonTabBar slot="bottom">
              <IonTabButton tab="tab1" href="/tab1">
                <IonIcon icon={mapOutline} />
                <IonLabel>Explore</IonLabel>
              </IonTabButton>
              <IonTabButton tab="tab2" href="/tab2">
                <IonIcon icon={homeOutline} />
                <IonLabel>Deals</IonLabel>
              </IonTabButton>
              <IonTabButton tab="tab3" href="/tab3">
                <IonIcon icon={walletOutline} />
                <IonLabel>Wallet</IonLabel>
              </IonTabButton>
            </IonTabBar>
          )}

This resulted in this error:

No overload matches this call.
  Overload 1 of 2, '(props: Readonly<BrowserRouterProps>): IonReactRouter', gave the following error.
    Type '{ children: Element; onChange: () => void; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<IonReactRouter> & Readonly<BrowserRouterProps> & Readonly<...>'.
      Property 'onChange' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes<IonReactRouter> & Readonly<BrowserRouterProps> & Readonly<...>'.
  Overload 2 of 2, '(props: BrowserRouterProps, context?: any): IonReactRouter', gave the following error.
    Type '{ children: Element; onChange: () => void; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<IonReactRouter> & Readonly<BrowserRouterProps> & Readonly<...>'.
      Property 'onChange' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes<IonReactRouter> & Readonly<BrowserRouterProps> & Readonly<...>'.

Is there another way to handle history hooking easily? I’ve tried about 1000 other methods at this point with no luck.

You can use the useLocation hook to be notified of URL changes. However that doesn’t work in the top-level App component, only in children components that have access to the router higher up in the component tree. So you may have to split your code into separate components.

Are you trying to show the tabs only when the user is logged in? There may be another approach in that case.

Essentially, I am also trying to hide the tabs when a user moves off of the tab pages because we are using back buttons for navigation for secondary pages. Pretty unfortunate that there isn’t an easier way to do this.

I’m thinking I’ll just use redux and set the state with with a dummy component inside of each page then.

Either that or create a page at the “/” level which handles it.

I agree, this is so annoying!!! I’m in the process of trying to figure out the same.

I solved the problem as in: Hide tabs when navigate/push to another page, it’s a bit hacky because it’s directly modifying the DOM but it works well.