i have unexpected behaviour. "user" variable that i declared at the top of App compenent is null by default.
At the first start or refresh of path=/, useEffect of App compenent gets executed before child compenent which is Login, What is the reason of this behaviour ?
App.js
import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom'
import { useAuthContext } from './hooks/useAuthContext'
import { useEffect }from 'react'
// pages & components
import Home from './pages/Home'
import Login from './pages/Login'
import Signup from './pages/Signup'
import Navbar from './components/Navbar'
function App() {
const { user } = useAuthContext()
useEffect(() => {
console.log("App useffect")
}, [])
return (
<div className="App">
<BrowserRouter>
<Navbar />
<div className="pages">
{console.log("Route main")}
<Routes>
<Route
path="/"
element={user ? <Home /> : <Navigate to="/login" /> }
/>
<Route
path="/login"
element={!user ? <Login /> : <Navigate to="/" />}
/>
<Route
path="/signup"
element={!user ? <Signup /> : <Navigate to="/" />}
/>
</Routes>
</div>
</BrowserRouter>
</div>
);
}
export default App;
Login.js
import { useEffect }from 'react'
const Login = () => {
console.log('Login here:')
useEffect(() => {
console.log("Login here:' useffect")
}, [])
return (
<div>Login</div>
)
}
export default Login
2
Answers
Navigate is a React component. According to documentation: "A element changes the current location when it is rendered.".
It means that your App.js is getting rendered and it renders the Navigate component first as you hit "/" route and then your App.js useEffect trigger. After component changes the location to "/login"- your Login.js is getting rendered by the react router and then useEffect in Login.js trigger.
This is what
<Navigate />
simply looks like,It also uses a
useEffect
to handle the side-effect ( replace the url ) and the render phase of the<Navigate />
returns justnull
.So it works as expected. It renders your App, then It renders your
<Navigate />
which returns null. Rendering completed and then it executed the side effects. Then after all of that, the side effect in the<Navigate />
is the one which causes to render<Login />
page.