Home > Enterprise >  react router login logout system
react router login logout system

Time:10-29

i am a beginner on reactjs.i am trying to make a login and logout system.it is expexted that when i login, the navbar will show a logout buttom.But i found that i have login to the page but the logout buttom on the navbar is not work here is my layout for navbar:

function Layout(props) {

const loginStatus=props.loginstatus;

return (
    <Navbar style={{"backgroundColor":"rgb(146, 212, 246)"}} variant='dark'expand="lg">
      <Container className="container" fluid >
        <Navbar.Brand href="/"><strong>STH News</strong></Navbar.Brand>
        <Navbar.Toggle aria-controls="navbarScroll" />
        <Navbar.Collapse id="navbarScroll">
          <Nav
            className="me-auto my-2 my-lg-0"
            style={{ 'fontSize': '20px' }}
            navbarScroll
          >
            <Nav.Link style={{'color':"white"}} href="/">Home</Nav.Link>
           
         {loginStatus ?
         <><form onSubmit={props.handlelogout}><Nav.Link style={{ 'color': "white" }} href='/' type='submit'>Logout</Nav.Link></form><NavDropdown style={{ 'color': "white" }} title="Your account" id="navbarScrollingDropdown">
          <NavDropdown.Item href="#action3">Stored News</NavDropdown.Item>
          <NavDropdown.Item href="#action4">
            History
          </NavDropdown.Item>
          <NavDropdown.Divider />
          <NavDropdown.Item href="#action5">
            Personal infomation
          </NavDropdown.Item>
        </NavDropdown></>:
        <Nav.Link style={{'color':"white"}} href="/login">Login</Nav.Link>
       }

        
        
       
      </Nav>

i use the index page for handling the function on login and logout.Here is my index.js:

export default function Index(){
 const [loginStatus,setLoginStatus]=useState({loginStatus:false}); 
 function handlelogout(){
  setLoginStatus({loginStatus:false})
  console.log("logouted")
 }
 
  
  return(
    <BrowserRouter>
    <Layout loginstatus={loginStatus} logout={handlelogout} />
    <Routes>
     
      <Route path="/" /> 
      
      <Route index element={<App />}/>
      <Route path="login" element={<Login  loginstatus={()=>{setLoginStatus(true);console.log("login")} }/>}/>
      

    </Routes>
    </BrowserRouter>
  )
} 

my login page:

const Login=(props)=>  {
    
    
    return (
        
        <><form onSubmit={props.loginstatus}><Button type='submit' variant="primary">Primary</Button></form>{/* <Link
        to={{pathname:'/layout',state:loginStatus}} /> */}</>);
    

}
 
export default Login;

the loginstatus is used to set the status ,but seems the problem is on handling the loginstatus in between the pages.

CodePudding user response:

I think the error is due to a typo in your Layout function. You have written

const loginStatus = props.loginstatus;

but both s should be capitalized like this:

const loginStatus = props.loginStatus;

CodePudding user response:

Issue

The issue is that the loginStatus state is an object with a loginStatus property.

const [loginStatus, setLoginStatus] = useState({ loginStatus: false });

function handlelogout() {
  setLoginStatus({ loginStatus: false });
  console.log("logged out");
}

but the code is not correctly accessing into this nested loginStatus property.

<Layout
  loginstatus={loginStatus} // <-- entire state passed here
  logout={handlelogout}
/>

...

function Layout(props) {
  const loginStatus = props.loginstatus; // <-- still entire state object
  ...

  return (
    ...
    {loginStatus // <-- defined object always truthy
      ? (
        <>
          ...
        </>
      ) : (
        <Nav.Link style={{'color':"white"}} href="/login">
          Login
        </Nav.Link>
      )
   }
  );

Solution

You have a few options available to you, ordered by what I'd suggest more strongly. I suggest also maintaining the loginStatus camelCasing naming convention to avoid confusion.

  1. Simplify the state to be the boolean value representing the authentication status.

    const [loginStatus, setLoginStatus] = useState(false);
    
    function handlelogout() {
      setLoginStatus(false);
      console.log("logged out");
    }
    
    <Layout
      loginStatus={loginStatus} // <-- boolean true/false
      logout={handlelogout}
    />
    
    function Layout({ loginStatus, logout }) {
      // loginStatus is boolean true/false
      ...
    
  2. Pass the nested state value.

    const [loginStatus, setLoginStatus] = useState({ loginStatus: false });
    
    function handlelogout() {
      setLoginStatus({ loginstatus: false });
      console.log("logged out");
    }
    
    <Layout
      loginStatus={loginStatus.loginStatus} // <-- boolean true/false
      logout={handlelogout}
    />
    
    function Layout({ loginStatus, logout }) {
      // loginStatus is boolean true/false
      ...
    
  3. Destructure/access into the passed object

    const [loginStatus, setLoginStatus] = useState({ loginStatus: false });
    
    function handlelogout() {
      setLoginStatus({ loginStatus: false });
      console.log("logged out");
    }
    
    <Layout
      loginStatus={loginStatus} // <-- object
      logout={handlelogout}
    />
    
    function Layout(props) {
      // props.loginStatus is object
      const { loginStatus } = props.loginStatus; // access boolean property
      ...
    
  • Related