React 移动导航在导航到另一条路线时不会自动关闭



我按照本教程构建了一个移动导航,这是一个很棒的教程,但我被卡住了。

当点击导航图标时,移动导航下拉菜单打开和关闭都没有问题。然而,当我点击下拉菜单链接并导航到另一个页面时,移动导航将保持打开状态,除非我自己手动关闭它。

路线发生变化时,如何关闭移动导航?

我感觉Navbar文件不太正确!但我似乎无法理解。任何建议都很好。

谢谢。

/// Navbar.jsx
import { Alert, Stack } from '@mui/material'
import React, { useContext, useState } from 'react'
import '../../styles/nav.css'
import { UserContext } from '../Contexts/User-Context'
const Navbar = (props) => {
const { loggedInUser } = useContext(UserContext)
const [open, setOpen] = useState(false)
const showSidebar = () => {
setOpen(!open)
}
const DropdownItem = (props) => {
return (
<div>
{ props.children }
</div>
)
}
return (
<div className='navbar'>
<h2 className='logo'>NC Games</h2>
<ul className='navbar-list'>
{ props.children }
</ul>
</div>
) 
}
export default Navbar
/// DropdownMenu.jsx
import React, { useContext, useEffect, useState } from 'react'
import { Link } from 'react-router-dom'
import { UserContext } from '../Contexts/User-Context'
const DropdownMenu = () => {
const { loggedInUser, setLoggedInUser } = useContext(UserContext)
const [open, setOpen] = useState(false)
const logOut = () => {
setLoggedInUser({ user: undefined })

}

const DropdownItem = (props) => {
return (
<div className='menu-item'>
{ props.children }
</div>
)
}

return loggedInUser ? (
<><div className='dropdown'>
<Link to={`/users/${loggedInUser.username}`}>
<DropdownItem className='nav-profile'>
<img className='nav-profile-pic' alt={loggedInUser.username} src={loggedInUser.avatar_url} />
</DropdownItem>
</Link>
<Link to={`/categories`}>

<DropdownItem>Categories</DropdownItem>
</Link>
<Link to={`/reviews`}>
<DropdownItem>Reviews</DropdownItem>
</Link>
<Link to={`/users`}>
<DropdownItem>Users</DropdownItem>
</Link>
<Link onClick={() => logOut()} to={`/`}>
<DropdownItem>Log out</DropdownItem>
</Link>
</div>
</>  
) : (
null
)
}
export default DropdownMenu
/// NavItem.jsx
import React, { useState } from 'react'
import '../../styles/nav.css'
const NavItem = (props) => {
const [open, setOpen] = useState(false)
console.log(open, "<< open");
return (
<li className='nav-item'>
<div onClick={() => setOpen(!open)}>
{ props.icon }
</div>
{ open && props.children }
</li>
)
}
export default NavItem
// App.jsx
function App() {
// const [user, setUser] = useState(null);
const [loggedInUser, setLoggedInUser] = useState(null);
const [loggedIn, setLoggedIn] = useState(false);
// const response = await axios.post()
const saveLoggedInUser = () => {
localStorage.setItem("user", JSON.stringify(loggedInUser));
};
const getLoggedInUser = () => {
if (localStorage.getItem("user") === null) {
localStorage.setItem("user", JSON.stringify(null));
} else {
let userLocal = JSON.parse(localStorage.getItem("user"));
setLoggedInUser(userLocal);
setLoggedIn(true);
}
};
useEffect(() => {
getLoggedInUser();
}, []);
useEffect(() => {
saveLoggedInUser();
}, [loggedInUser, loggedIn]);
useEffect(() => {
window.scrollTo(50, 50)
}, [])
const isLoggedIn = loggedInUser !== null;
return (
<BrowserRouter>
<UserContext.Provider
value={{ loggedInUser, setLoggedInUser, isLoggedIn }}
>
<div className="App">
<Navbar>
<NavItem icon={<MenuRoundedIcon />}>
<DropdownMenu />
</NavItem>
</Navbar>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/categories" element={<Categories />} />
<Route path="/reviews/:category" element={<ReviewList />} />
<Route path="/reviews" element={<ReviewList />} />
<Route path="/review/:review_id" element={<ReviewPage />} />
<Route path="/users" element={<Users />} />
<Route path="/users/:username" element={<User />} />
</Routes>
</div>
</UserContext.Provider>
</BrowserRouter>
);
}
/// Nav.css
* {
margin: 0px;
}
:root {
--bg: #242526;
--bg-accent: #484a4d;
--nav-size: 60px;
--border: 1px solid #474a4d;
--border-radius: 8px;
--speed: 500ms;
/* margin-top: 75px; */
}
ul {
list-style: none;
margin: 0;
padding: 0;
} 

a {
/* color: #dadce1; */
text-decoration: none;
}
.logo {
color: #dadce1;
margin: 0px;
display: flex;
align-items: center;
}
.navbar {
height: var(--nav-size);
background-color: var(--bg);
padding: 0 1rem;
border-bottom: var(--border);
display: flex;
justify-content: space-between;
position: fixed;
z-index: 1000;
top: 0;
width: 100%;
}
.navbar-list {
max-width: 100%;
height: 100%;
display: flex;
justify-content: flex-end;
}
.nav-item {
width: calc(var(--nav-size) * 0.8);
display: flex;
align-items: center;
justify-content: center;
margin-right: 25px;
color: #dadce1;
}
.icon-button {
--button-size: calc(var(--nav-size) * 0.5);
width: var(--button-size);
height: var(--button-size);
/* background-color: #484a4d;  */
border-radius: 50%;
padding: 5px;
margin: 2px;
display: flex;
justify-content: center;
align-items: center;
}
.dropdown {
position: absolute;
z-index: 1;
top: 56px;
width: 300px;
transform: translateX(-35%);
background-color: var(--bg);
border: var(--border);
border-radius: var(--border-radius);
padding: 1rem;
overflow: hidden;
display: flex;
flex-direction: column;
opacity: 1;
}
.menu-item {
height: 50px;
display: flex;
flex-direction: column;
text-align: center;
align-items: center;
justify-content: center;
border-radius: var(--border-radius);
/* transition: background var(--speed);  */
padding: 0.5rem;
}
.menu-item:hover {
background-color: #525357;
} 
.nav-profile-pic {
max-width: 75px;
padding-bottom: 40px 0px 40px 0px;
object-fit: contain;
overflow: hidden;
border-radius: 50%;
}

是否在每条路线内定义了NavBar组件?

我认为,如果你将导航栏移动到每个页面,那么默认情况下,每次路线更改时,标题/导航栏都应该重新初始化。

您还可以使用useLocation((并从中析构函数路径名。然后使用useEffect来监控更改,并关闭更改下拉菜单:

const { path } = useLocation();
useEffect(() =>{
setDropDownOpen(false);
}, [path])

最新更新