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.
You may use
useLocation
hook which will cause a rerender when the location changes.useLocation
hook must be used inside ofRouter
component, So you should rearrange your components in a way thatNavbar
component is rendered when user is insideRouter
component.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;