skip to Main Content

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


  1. 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.

    Login or Signup to reply.
  2. This is what <Navigate /> simply looks like,

    function Navigate() {
      React.useEffect(
        () => navigate(JSON.parse(jsonPath), { replace, state, relative }),
        [navigate, jsonPath, relative, replace, state]
      );
    
      return null;
    }
    

    It also uses a useEffect to handle the side-effect ( replace the url ) and the render phase of the <Navigate /> returns just null.

    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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search