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