Home > other >  React Router Conditional Rendering of NavBar
React Router Conditional Rendering of NavBar

Time:08-07

I've a navbar that i want to hide when the user is logged in.I don't want to display the NavBar when the user is at the '/auth' endpoint. I tried a conditional rendering but it doesn't work.

Code :

import React from 'react';
import Navbar from './Navbar';
import { BrowserRouter as Router, Routes, Route ,Navigate} from 'react-router-dom';
import {Login} from './Login';
import {SignUp} from './SignUp'
import { Home } from './Home';
import Freecomponent from './Freecomponent';
import AuthComponent from './AuthComponent';
import Cookies from 'universal-cookie';

function App() {
    const cookies = new Cookies();
    
return (
    <Router>
    {window.location.href === '/auth' ? null :  <Navbar />}
    <Routes>
    
        <Route path='/' element={<div><Home /></div>} exact />
        <Route path='/signup' element={<SignUp />} />
        <Route path='/signin' element={<Login />} />
        <Route path='/free' element={<Freecomponent />} />
        <Route path='/auth' element={cookies.get("TOKEN") ? <AuthComponent /> : <Navigate to='/' />} />
        
    </Routes>
    </Router>
);
}

export default App;

CodePudding user response:

React components are rendered whenever their props, state or context change. In your case window.location.href is none of the above. So when URL changes, React will not rerender App component.

  1. You may use useLocation hook which will cause a rerender when the location changes. useLocation hook must be used inside of Router component, So you should rearrange your components in a way that Navbar component is rendered when user is inside Router component.

  2. Store the status of the user(whether or not they are logged in or not, their JWT, etc in a state) which make React to rerender App component. You can use either state or context for that.

Edit:

function App() {
  // isLoggedIn should be read from state, props or context to make React to rerender this component
  const isLoggedIn = ...

  if (isLoggedIn) {
    return (
      <Routes>// Whatever you want to render when user is logged in</Routes>
    );
  }

  return <Routes>// Whatever you want to render when user is not logged in</Routes>;
}

Also as far as I remember, you can only render Route component inside Routes. There could be some workarounds but they are not needed.

CodePudding user response:

So this is the solution i came up with , i used Outlet from react-router-dom.

Code :

import React from 'react';
import Navbar from './Navbar';
import { BrowserRouter as Router, Routes, Route ,Navigate,Outlet} from 'react-router-dom';
import {Login} from './Login';
import {SignUp} from './SignUp'
import { Home } from './Home';
import Freecomponent from './Freecomponent';
import AuthComponent from './AuthComponent';
import Cookies from 'universal-cookie';

function App() {
    const cookies = new Cookies();
    
return (
    <Router>
    <Routes>
    <Route path='/' element={<Layout />}>
        <Route index element={<div><Home /></div>} exact />
        <Route path='/signup' element={<SignUp />} />
        <Route path='/signin' element={<Login />} />
        <Route path='/free' element={<Freecomponent />} />
    </Route>
    <Route path='/auth' element={cookies.get("TOKEN") ? <AuthComponent /> : <Navigate to='/' />} /> 
    </Routes>
    </Router>
);
}
 function Layout () {
    return (
        <div>
            <Navbar />
            <div className="container">
              
              <Outlet />
            </div>
        </div>
    )
}

export default App;
  • Related