1

I am trying to display two different navbar component one as the main site navbar and one for the dashboard navbar.

I have tried creating two reusable components namely:

<LayoutNav /> and <DashboardNav />

Here is their implementation:

const LayoutNav = ({children}) => {
    return (
        <>
            <section className="container-fluid">
                <Navbar />
                {children}
            </section>
        </>
    );
}

it is the same for LayoutDashboardNav i only changed <Navbar /> to <DashboardNav /> below is my route implementation:

<BrowserRouter>
        <Switch>
            <LayoutNav>
                <Route exact path="/registervehicle" component={RegVehicle} />
                <Route exact path="/result" component={SearchResults} />
                <Route exact path="/selectseat" component={PickSeat} />
                <Route exact path="/forgotpassword" component={ForgotPassword} />
                <Route exact path="/resetpassword" component={ResetPassword} />
                <Route exact path="/register" component={Registration} />
                <Route exact path="/login" component={LoginAuth} />
                <Route exact path="/" component={Home} />
            </LayoutNav>

            <LayoutDashboardNav>
                <Route exact path="/companydashboard" component={CompanyDashboard} />
            </LayoutDashboardNav>

            <Route component={NotFound} />
        </Switch>
        <Footer />
    </BrowserRouter>

I expect to see <Navbar /> or <DashboardNav /> only on those pages that are children of the components they are used in. But everything is showing only <Navbar />.

1 Answers1

1

You can use a a higher order component to wrap the <Route> component like this. We can have the wrapper component to have some logic to determine which layout to use based on layout prop.

// wrapper component
const DynamicLayoutRoute = props => {
  const { component: RoutedComponent, layout, ...rest } = props;

  // render actual Route from react-router
  const actualRouteComponent = (
    <Route
      {...rest}
      render={props => (
         <RoutedComponent {...props} />
      )}
    />
  );

  // depends on the layout, you can wrap Route component in different layouts
  switch (layout) {
    case 'NAV': {
      return (
        <LayoutNav>
          {actualRouteComponent}
        </LayoutNav>
      )
    }
    case 'DASH_BOARD_NAV': {
      return (
        <LayoutDashboardNav>
          {actualRouteComponent}
        </LayoutDashboardNav>
      )
    }
    default: {
      return (
        <LayoutNav>
          {actualRouteComponent}
        </LayoutNav>
      )
    }
  }
};

Instead of doing the normal <Route exact path="/selectseat" component={PickSeat} />

Now you can do <DynamicLayoutRoute exact path="/selectseat" component={PickSeat} layout="DASH_BOARD_NAV" />

Siraj Alam
  • 5,569
  • 5
  • 39
  • 55
Andrew Zheng
  • 1,164
  • 7
  • 15
  • I cant make this work - when i try to implement, it says "userContext is not defined" - what is the plane with userContext in this case? – implum Jul 08 '20 at 07:45
  • @implum I updated the answer. The "userContext" section shouldn't be there at all. Sorry for the confusion. – Andrew Zheng Jul 08 '20 at 13:21
  • im still struggling - it just says 'Cannot read property of 'props' of undefined and then referring to this: const DynamicLayoutRoute = props => { const { component: RoutedComponent, layout, ...rest } = this.props; // render actual Route from react-router const actualRouteComponent = ( – implum Jul 13 '20 at 07:42
  • see here if you can help: https://stackoverflow.com/questions/62871525/higher-order-component-showing-different-navigation-on-different-pages – implum Jul 13 '20 at 08:05