skip to Main Content
import './App.css';
import { BrowserRouter as Router, Routes, Route, Navigate } from 'react-router-dom';
import { useEffect, useState } from 'react';
import MyHome from './components/MyHome';
import Header from './components/Header';
import Footer from './components/Footer';
import CommentList from './components/CommentList'
import PostComment from './components/PostComment';
import SignUp from './components/SignUp';
import SignIn from './components/SignIn';
import EmailVerification from './components/EmailVerification';
import Cookies from 'universal-cookie'
import NavigationBar from './components/NavigationBar';
import Takeaway from './components/Takeaway';
import TakeawayChinese from './components/TakeawayChinese';

function App() {
  const [logInState, setLogInState] = useState(false);
  const cookies = new Cookies()

  const handleLogout = () => {
    setLogInState(false);
    cookies.remove('Token');
    localStorage.clear();
  }

  const checkTokenExpiration = () => {
    const cookiesToken = cookies.get('Token')
    const localStorageToken = localStorage.getItem('Token');
    const expirationTime = localStorage.getItem('TokenExpiration');

    if (cookiesToken && localStorageToken && expirationTime) {
      const currentTime = new Date().getTime();

      if (currentTime > Number(expirationTime)) { handleLogout(); }
      else { setLogInState(true); }
    }
  };

  useEffect(() => {
    checkTokenExpiration();
    const interval = setInterval(checkTokenExpiration, 1000); 
    return () => clearInterval(interval);
  }, []);

  return (
    <div className="App">
      <NavigationBar logInState={logInState} handleLogout={handleLogout} />
      <Header />

      <Routes>
        <Route path='/' element={<MyHome />} />
        <Route path="/commentlist" element={<CommentList logInState={logInState} />} />

        <Route
          path="/postcomment"
          element={
            logInState ? (
              <PostComment />
            ) : (
              // <Navigate to="/signin" />
              <SignIn />
            )
          }
        />

        <Route
          path="/signup"
          element={
            logInState ? (
              <Navigate to="/" />
            ) : (
              <SignUp />
            )
          }
        />

        <Route
          path="/signin"
          element={
            logInState ? (
              <Navigate to="/" />
            ) : (
              <SignIn setLogInState={setLogInState} />
            )
          }
        />

        <Route path="/emailverification/:token" element={<EmailVerification />} />
        <Route path='/takeaway' element={<Takeaway />} />
        <Route path='/takeawaychinese' element={<TakeawayChinese />} />
      </Routes>


      <Footer />
    </div >
  );
}
export default App;

"/postcomment" route is not working properly:

<Navigate to="/signin" >

After logged in, the above route takes the user to home page instead of postcomment page.

But it works fine if i change to the below route

<SignIn >

Does anyone know why Navigate component is causing the bug?

or are there better ways of doing it if I need to use a log-in state to control the routes?

2

Answers


  1. Chosen as BEST ANSWER

    i noticed its the bootstrap components causing the bug, the postcomment navbar link works if i used original react tags (the commented out section), even if i use Navigate component in app.js file does anyone know why?

        <Route
                  path="/postcomment"
                  element={
                    logInState ? (
                      <PostComment />
                    ) : (
                      <Navigate to="/signin" />
                      // <SignIn />
                    )
                  }
                />
        
        import React, { useState } from 'react'
        import { Container, Nav, NavDropdown, Navbar, NavbarBrand, Button, Offcanvas } from 'react-bootstrap'
        import { Link, NavLink } from 'react-router-dom'
        
        const NavigationBar = ({ logInState, handleLogout }) => {
            return (
                // <div>
                //     <NavLink to="/" >Home</NavLink><br />
                //     <NavLink to="/takeaway" >Takeaway  Menu</NavLink><br />
                //     <NavLink to="/takeawaychinese" >Takeaway Chinese Menu</NavLink><br />
                //     {logInState ? (
                //         <>
                //             <NavLink to="/postcomment">Post comment</NavLink><br />
                //             <button onClick={handleLogout}>Logout</button><br />
                //         </>
                //     ) : (
                //         <>
                //             <NavLink to="/signup">Sign up</NavLink><br />
                //             <NavLink to="/signin">Sign in</NavLink>
                //         </>
                //     )}
                // </div>
    
            <Navbar className="bg-body-tertiary custom-navbar" collapseOnSelect expand="lg" Navbar sticky='top' bg="dark" data-bs-theme="dark" >
                <Container>
                    <Navbar.Brand href="/">
                        <img
                            src="../../public/logo192.png"
                            alt="Logo"
                            width="30"
                            height="30"
                            className="d-inline-block align-top"
                        />
                        Logo
                    </Navbar.Brand>
    
                    {/* appear when minimized */}
                    <Navbar.Toggle aria-controls="responsive-navbar-nav" />
    
                    <Navbar.Collapse id="responsive-navbar-nav">
                        <Nav className="me-auto justify-content-between" >
                            <Nav.Link href="/">Home</Nav.Link>
                            <Nav.Link href='/takeaway'>Takeaway Menu</Nav.Link>
                            <Nav.Link href='/takeawaychinese'>Takeaway Chinese Menu</Nav.Link>
                            <Nav.Link href='/aboutus'>About Us</Nav.Link>
    
                            <NavDropdown title="Comment" id="responsive-nav-dropdown" align="end">
                                <NavDropdown.Item href='/commentlist'>Comment list</NavDropdown.Item>
    
                                {logInState ? (
                                    <>
                                        <NavDropdown.Item href="/postcomment">postcomment</NavDropdown.Item>
                                        <NavDropdown.Divider />
                                        <NavDropdown.Item onClick={handleLogout} className="dropdown-item" id='dropdown-item-button'>Logout</NavDropdown.Item>
                                    </>
                                ) : (
                                    <>
                                        <NavDropdown.Item href="/signup">Sign up</NavDropdown.Item>
                                        <NavDropdown.Item href="/signin">Sign in</NavDropdown.Item>
                                    </>
                                )}
                            </NavDropdown>
                        </Nav>
                    </Navbar.Collapse>
    
    
                </Container>
            </Navbar>
        )
    }
    
    export default NavigationBar
    

  2. It’s possible that the logInState update is asynchronous and the navigation is triggered before the state is updated properly. This can happen if the login state update is delayed or if there’s a race condition.

    // ProtectedRoute.js
    import { Route, Navigate } from 'react-router-dom';
    
    function ProtectedRoute({ element, requireAuth, ...rest }) {
      // Logic to determine whether the user should be authenticated
      if (requireAuth && !logInState) {
        return <Navigate to="/signin" />;
      }
    
      return <Route {...rest} element={element} />;
    }
    
    export default ProtectedRoute;
    

    Then, in your main App component, you can use the ProtectedRoute wrapper like this:

    import ProtectedRoute from './ProtectedRoute';
    
    // ...
    
    <ProtectedRoute
      path="/postcomment"
      element={<PostComment />}
      requireAuth={true} // Require authentication for this route
    />
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search