React router dom add headers and dashboard for certain routes

Viewed 1017

I am using react router dom Version 5 in my react version 15 application, I want to know how I can display the page header and the dashboard in all the pages except the authentication and the sign up pages.

I tried to do a test on the pathname but I always had a lag when I change pages or when I try to disconnect, I have to refresh the page each time. Here's my code :

          <Router>
            {pathname !=='/' && pathname !== '/sign-in' && pathname !== '/sign-up' && 
              <>
                <Header></Header>
                <Dashboard ></Dashboard> 
              </>  
            }
          <Switch>
                <Route exact path='/' component={SignIn} />
                <Route path="/sign-in" component={SignIn} />
                <Route path="/sign-up" component={SignUp} />
                {
                  sessionStorage.getItem("token") === null ?
                  <Redirect  to='/sign-in'/>  :
                  <>
                  <Route path="/home" component={Home} />
                  <Route path="/management" component={Management} />
                  <Redirect  to='/home'/>  :

                </>
                }
                
          </Switch>
          </Router>

EDIT : I'm trying with render inside route tag ,It's worked fine. But, I would like to optimize my code :

          <Router>
          <Switch>
                <Route exact path='/' component={SignIn} />
                <Route path="/sign-in" component={SignIn} />
                <Route path="/sign-up" component={SignUp} />
                {
                  sessionStorage.getItem("token") === null ?
                  <Redirect  to='/sign-in'/>  :
                  <>
                  <Route path="/home" render={() =><> <Header/> 
                  <Dashboard/><Home/></>} />
                  <Route path="/management"  render={() =><> <Header/> 
                  <Dashboard /><Management/></>} />
                  <Redirect  to='/home'/>  :

                </>
                }
                
          </Switch>
          </Router>


1 Answers

In react-router-dom v5 you can render the Header and Dashboard into a Route with an array of paths you want them to be rendered on. Render the Route within the Router but outside the Switch so it can be inclusively matched and rendered.

Example:

<Router>
  <Route path={["/home", "/management]}>
    <>
      <Header />
      <Dashboard /> 
    </>
  </Route>
  <Switch>
    <Route path="/sign-in" component={SignIn} />
    <Route path="/sign-up" component={SignUp} />
    {sessionStorage.getItem("token") === null
      ? <Redirect  to='/sign-in'/>
      : (
        <>
          <Route path="/home" component={Home} />
          <Route path="/management" component={Management} />
          <Redirect  to='/home'/>
        </>
    )}      
    <Route path='/' component={SignIn} />
  </Switch>
</Router>

If the number of routes to allow far outnumbers the routes to want to hide the header and dashboard, then use the children render function and access the location prop.

<Router>
  <Route 
    children={({ location }) => {
      return !["/", "/sign-in", "/sign-up"].includes(location.pathname)
        ? (
          <>
            <Header />
            <Dashboard /> 
          </>
        )
        : null;
    }}
  />
  <Switch>
    <Route exact path='/' component={SignIn} />
    <Route path="/sign-in" component={SignIn} />
    <Route path="/sign-up" component={SignUp} />
    {sessionStorage.getItem("token") === null
      ? <Redirect  to='/sign-in'/>
      : (
        <>
          <Route path="/home" component={Home} />
          <Route path="/management" component={Management} />
          <Redirect  to='/home'/>
        </>
    )}      
  </Switch>
</Router>

Or abstract the header and dashboard into a component that uses the useRouteMatch hook to test against an array of routes to be excluded on.

const HeaderDash = () => {
  const isExcludedMatch = useRouteMatch({
    path: ["/", "/sign-in", "/sign-up"],
    exact: true,
  });
  return isExcludedMatch
    ? null
    : (
      <>
        <Header />
        <Dashboard /> 
      </>
    );
};

...

<Router>
  <Route component={HeaderDash} />
  <Switch>
    <Route exact path='/' component={SignIn} />
    <Route path="/sign-in" component={SignIn} />
    <Route path="/sign-up" component={SignUp} />
    {sessionStorage.getItem("token") === null
      ? <Redirect  to='/sign-in'/>
      : (
        <>
          <Route path="/home" component={Home} />
          <Route path="/management" component={Management} />
          <Redirect  to='/home'/>
        </>
    )}      
  </Switch>
</Router>
Related