[英]I want to change my navbar from login to logout when the user is already login ESJ NodeJs
[英]How can I change this Navbar dropdown item to update from "Login" to "Logout" when a user logs in?
我正在尝试更新我的Navbar
组件,以便当用户登录时,导航栏下拉项“登录”更改为“注销”,但我遇到了问题。 我是 React 和 JS 的新手,但作为我 go 学习,所以对于这个问题中的任何混淆,我深表歉意。 我的Navbar
、 Dropdown
、 Footer
以及用户想要查看的每个页面都有 jsx 组件,这些页面在我的App.js
文件中呈现。
导航栏.jsx:
import React, {useState, useEffect} from 'react';
import {Link} from 'react-router-dom';
import './Navbar.css';
import Dropdown from './Dropdown';
import {NavItemsList} from './NavItemsList';
import NavItems from './NavItems';
function Navbar() {
const [click, setClick] = useState(false);
const [button, setButton] = useState(true);
const [dropdown, setDropdown] = useState(false);
const handleClick = () => setClick(!click);
const closeMobileMenu = () => setClick(false);
const onMouseEnter = () => {
if (window.innerWidth < 960) {
setDropdown(false);
} else {
setDropdown(true);
}
};
const onMouseLeave = () => {
if (window.innerWidth < 960) {
setDropdown(false);
} else {
setDropdown(false);
}
};
return (
<>
<nav className='navbar'>
<div className='navbar-container-whole'>
<div className='left-nav-container'>
{/* Link in react-router-dom essentially replaces a tag.*/}
<Link to='/' className='navbar-logo'>
<img src='/images/logo.png' className='hashtek-logo' alt='logo' />
<h1 className='navbar-name'>HashTek</h1>
</Link>
</div>
{/* .navbar-container will create a div with that class name. */}
<div className='center-nav-container'>
<form action='./' method='get' id='search-form'>
<div class='searchbar'>
<input
class='searchbar_input'
type='search'
name='search'
placeholder='Search..'
/>
<button type='submit' class='searchbar_button'>
<i class='material-icons'>search</i>
</button>
</div>
</form>
</div>
<div className='right-nav-container'>
<ul className={click ? 'nav-menu active' : 'nav-menu'}>
<div className='text-links'>
{/* This line above is for when you are on mobile, and an item is clicked, the nav menu will disappear */}
{NavItemsList.slice(0, 4).map((menu, index) => {
return <NavItems items={menu} key={index} />;
})}
</div>
<div className='logo-links'>
{NavItemsList.slice(4, 6).map((menu, index) => {
return <NavItems items={menu} key={index} />;
})}
</div>
</ul>
<div className='menu-icon' onClick={handleClick}>
<i className={click ? 'fas fa-times' : 'fas fa-bars'} />
</div>
</div>
</div>
</nav>
</>
);
}
export default Navbar;
NavItemsList.js:
export const NavItemsList = [
{
title: 'Products',
path: '/products',
cName: 'nav-links',
},
{
title: 'Stats',
path: '/stats',
cName: 'nav-links',
},
{
title: 'Contacts',
path: '/contacts',
cName: 'nav-links',
subNav: [
{
title: 'About',
path: '/contacts/about',
cName: 'dropdown-link',
menuName: 'contacts-menu',
},
{
title: 'How To',
path: '/contacts/how-to',
cName: 'dropdown-link',
menuName: 'contacts-menu',
},
{
title: 'Developers',
path: '/contacts/developers',
cName: 'dropdown-link',
menuName: 'contacts-menu',
},
{
title: 'Designers',
path: '/contacts/designers',
cName: 'dropdown-link',
menuName: 'contacts-menu',
},
{
title: 'Mentors',
path: '/contacts/mentors',
cName: 'dropdown-link',
menuName: 'contacts-menu',
},
],
},
{
title: 'Services',
path: '/services',
cName: 'nav-links',
subNav: [
{
title: 'Streaming',
path: '/services/streaming',
cName: 'dropdown-link',
menuName: 'services-menu',
},
{
title: 'Editing',
path: '/services/editing',
cName: 'dropdown-link',
menuName: 'services-menu',
},
],
},
{
title: Account,
path: '/my-account',
cName: 'nav-links',
subNav: [
{
title: 'Login',
path: '/login',
cName: 'dropdown-link',
menuName: 'account-menu',
},
{
title: 'Profile',
path: '/profile',
cName: 'dropdown-link',
menuName: 'account-menu',
},
],
},
{
title: Help,
path: '/help',
cName: 'nav-links',
},
];
下拉.jsx:
import React, {useState} from 'react';
import {Link} from 'react-router-dom';
import './Dropdown.css';
function Dropdown(props) {
const [click, setClick] = useState(false);
const handleClick = () => setClick(!click);
const submenus = props.submenus;
return (
<ul
onClick={handleClick}
className={click ? 'dropdown-menu clicked' : 'dropdown-menu'}
>
{submenus.map((subNav, index) => (
<div className={subNav.menuName}>
<li key={index} className='dropdown-links'>
<Link
className={subNav.cName}
to={subNav.path}
onClick={() => setClick(false)}
>
{subNav.title}
</Link>
</li>
</div>
))}
</ul>
);
}
export default Dropdown;
导航项.jsx:
import React, {useState} from 'react';
import Dropdown from './Dropdown';
import {Link} from 'react-router-dom';
function NavItems(props) {
const items = props.items;
const [click, setClick] = useState(false);
const handleClick = () => setClick(!click);
const [dropdown, setDropdown] = useState(false);
const onMouseEnter = () => {
if (window.innerWidth < 960) {
setDropdown(false);
} else {
setDropdown(true);
}
};
const onMouseLeave = () => {
if (window.innerWidth < 960) {
setDropdown(false);
} else {
setDropdown(false);
}
};
return (
<div className='link-container' onMouseLeave={onMouseLeave}>
<li className='nav-item'>
{items.subNav ? (
<>
<Link
className={items.cName}
to={items.path}
onClick={() => setClick(false)}
onMouseEnter={onMouseEnter}
>
{items.title}
</Link>
{dropdown && <Dropdown submenus={items.subNav} />}
</>
) : (
<Link
className={items.cName}
to={items.path}
onClick={() => setClick(false)}
>
{items.title}
</Link>
)}
</li>
</div>
);
}
export default NavItems;
我正在关注一个在其 App.js 文件中实现导航栏的教程,如下所示:
import React, { useState, useEffect, useCallback } from "react";
import { useDispatch, useSelector } from "react-redux";
import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";
import "bootstrap/dist/css/bootstrap.min.css";
import "./App.css";
import Login from "./components/Login";
import Register from "./components/Register";
import Home from "./components/Home";
import Profile from "./components/Profile";
import BoardUser from "./components/BoardUser";
import BoardModerator from "./components/BoardModerator";
import BoardAdmin from "./components/BoardAdmin";
import { logout } from "./slices/auth";
import EventBus from "./common/EventBus";
const App = () => {
const [showModeratorBoard, setShowModeratorBoard] = useState(false);
const [showAdminBoard, setShowAdminBoard] = useState(false);
const { user: currentUser } = useSelector((state) => state.auth);
const dispatch = useDispatch();
const logOut = useCallback(() => {
dispatch(logout());
}, [dispatch]);
useEffect(() => {
if (currentUser) {
setShowModeratorBoard(currentUser.roles.includes("ROLE_MODERATOR"));
setShowAdminBoard(currentUser.roles.includes("ROLE_ADMIN"));
} else {
setShowModeratorBoard(false);
setShowAdminBoard(false);
}
EventBus.on("logout", () => {
logOut();
});
return () => {
EventBus.remove("logout");
};
}, [currentUser, logOut]);
return (
<Router>
<div>
<nav className="navbar navbar-expand navbar-dark bg-dark">
<Link to={"/"} className="navbar-brand">
bezKoder
</Link>
<div className="navbar-nav mr-auto">
<li className="nav-item">
<Link to={"/home"} className="nav-link">
Home
</Link>
</li>
{showModeratorBoard && (
<li className="nav-item">
<Link to={"/mod"} className="nav-link">
Moderator Board
</Link>
</li>
)}
{showAdminBoard && (
<li className="nav-item">
<Link to={"/admin"} className="nav-link">
Admin Board
</Link>
</li>
)}
{currentUser && (
<li className="nav-item">
<Link to={"/user"} className="nav-link">
User
</Link>
</li>
)}
</div>
{currentUser ? (
<div className="navbar-nav ml-auto">
<li className="nav-item">
<Link to={"/profile"} className="nav-link">
{currentUser.username}
</Link>
</li>
<li className="nav-item">
//INTERESTED IN THIS
<a href="/login" className="nav-link" onClick={logOut}>
</a>
</li>
</div>
) : (
<div className="navbar-nav ml-auto">
<li className="nav-item">
<Link to={"/login"} className="nav-link">
Login
</Link>
</li>
<li className="nav-item">
<Link to={"/register"} className="nav-link">
Sign Up
</Link>
</li>
</div>
)}
</nav>
<div className="container mt-3">
<Switch>
<Route exact path={["/", "/home"]} component={Home} />
<Route exact path="/login" component={Login} />
<Route exact path="/register" component={Register} />
<Route exact path="/profile" component={Profile} />
<Route path="/user" component={BoardUser} />
<Route path="/mod" component={BoardModerator} />
<Route path="/admin" component={BoardAdmin} />
</Switch>
</div>
</div>
</Router>
);
};
export default App;
据我所知,他们正在检查currentUser
的Navbar
,如果有,则导航栏将更新以显示注销和当前用户的用户名。 这是我遇到麻烦的地方,因为我决定改为将数组导入我的Navbar
。 我是否需要更改Navbar
以便它在不使用NavItemsList
的情况下直接呈现Navbar
组件中的项目,或者我是否可以检查 state 并将“登录”更改为“注销”而不更改我的NavItemsList
组件太多了? 任何帮助将不胜感激,我一直在摸索如何在不重构我的辛勤工作的情况下解决这个问题 go。
我建议您应该在链接和路由配置中添加一个“身份验证状态”属性,以便在将它们映射到 UI 时可以检查当前的身份验证状态并呈现适当的内容。
例子:
export const NavItemsList = [
...
{
title: Account,
path: '/my-account',
cName: 'nav-links',
subNav: [
{
title: 'Login',
path: '/login',
cName: 'dropdown-link',
menuName: 'account-menu',
authenticated: false,
},
{
title: 'Logout',
path: '/logout',
cName: 'dropdown-link',
menuName: 'account-menu',
authenticated: true,
},
{
title: 'Profile',
path: '/profile',
cName: 'dropdown-link',
menuName: 'account-menu',
},
],
},
...
];
...
function Dropdown({ submenus }) {
const { user: currentUser } = useSelector((state) => state.auth);
const [click, setClick] = useState(false);
const handleClick = () => setClick(click => !click);
return (
<ul
onClick={handleClick}
className={click ? 'dropdown-menu clicked' : 'dropdown-menu'}
>
{submenus
.filter(({ authenticated }) => {
if (authenticated !== undefined) {
return !!currentUser === authenticated;
}
return true;
})
.map((subNav) => (
<div key={subNav.path} className={subNav.menuName}>
<li className='dropdown-links'>
<Link
className={subNav.cName}
to={subNav.path}
onClick={() => setClick(false)}
>
{subNav.title}
</Link>
</li>
</div>
))
}
</ul>
);
}
我最好在 NavItem 中做这样的事情
{subNav.title==='Login'?(userLoggedIn?'Logout':'Login'):subNav.title}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.