0

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
  • @slebetman that isn't accurate. `useEffect` always runs after first render as 'componentDidMount' – pilchard May 25 '23 at 12:51
  • Does this answer your question? [What is the correct order of execution of useEffect in React parent and child components?](https://stackoverflow.com/questions/58352375/what-is-the-correct-order-of-execution-of-useeffect-in-react-parent-and-child-co) – pilchard May 25 '23 at 12:52
  • I dont get same behaviour when i directly request to /login compenent. It renders (mounts) child compenent excutes useEffect of that child copmenent and after then starts to executing the parent's useEffects. I didint get the answer unfortunately. @slebetman – Cihangir Köroğlu May 25 '23 at 12:52
  • It looks like it is based on routing as described in the answer – pilchard May 25 '23 at 12:53
  • Nah it is not @pilchard i know the executing lifecycle of useEffect but this example that im asking is not proper with lifecycle, thats what i didnt understand – Cihangir Köroğlu May 25 '23 at 12:55

2 Answers2

0

Navigate is a React component. According to documentation: "A <Navigate> 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 <Navigate> component changes the location to /login- your Login.js is getting rendered by the react router and then useEffect in Login.js trigger.

hkanjih
  • 1,271
  • 1
  • 11
  • 29
cornor
  • 16
  • 3
0

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.

Dilshan
  • 2,797
  • 1
  • 8
  • 26