繁体   English   中英

当用户登录时,如何更改此导航栏下拉项以从“登录”更新为“注销”?

[英]How can I change this Navbar dropdown item to update from "Login" to "Logout" when a user logs in?

我正在尝试更新我的Navbar组件,以便当用户登录时,导航栏下拉项“登录”更改为“注销”,但我遇到了问题。 我是 React 和 JS 的新手,但作为我 go 学习,所以对于这个问题中的任何混淆,我深表歉意。 我的NavbarDropdownFooter以及用户想要查看的每个页面都有 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;

据我所知,他们正在检查currentUserNavbar ,如果有,则导航栏将更新以显示注销和当前用户的用户名。 这是我遇到麻烦的地方,因为我决定改为将数组导入我的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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM