Gatsbyjs 中的自定义导航栏
Posted
技术标签:
【中文标题】Gatsbyjs 中的自定义导航栏【英文标题】:Custom Navbar in Gatsbyjs 【发布时间】:2021-12-13 03:25:07 【问题描述】:我遇到了自定义导航栏的问题。我不会撒谎,我确实复制了它,但我想让它变得更好。我遇到的具体问题是在移动端。当我单击导航栏中的链接时,导航栏菜单不会消失。它停留在外面,页面加载到点击的链接。如何使用 useEffect 或 State 或 props 使导航栏滑出视图?
顺便说一句,tailwindCss 和 bootstrap 对我来说是不可能的,因为我想使用样式化组件并提高我的 css 技能。
感谢任何反馈。
编辑代码:
import React, useState, useEffect, useRef from "react";
import styled from "styled-components";
import Link from "gatsby";
const Navigation = styled.nav`
display: flex;
position: sticky;
position: -webkit-sticky;
position: -moz-sticky;
position: -ms-sticky;
position: -o-sticky;
background-color: var(--white);
justify-content: space-between;
text-transform: uppercase;
border-bottom: 2px solid var(--light-green-shadow);
width: 100%;
margin: 0;
top: 0;
padding: 0.5rem 0;
z-index: 2;
align-items: center;
box-sizing: border-box;
transition: background ease-out 300ms;
background: $( background ) => background ? `var(--light-green-tint)` : `var(--light-green)`;
@media (max-width: 768px)
height: 5vh;
position: sticky;
top: 0;
left: 0;
right: 0;
left: 0;
`
const Toggle = styled.div`
display: none;
height: 100%;
cursor: pointer;
padding: 0 10vw;
@media (max-width: 768px)
display: flex;
`
const Navbox = styled.div`
display: flex;
height: 100%;
justify-content: flex-end;
align-items: center;
box-sizing: border-box;
ul
display: flex;
align-items: center;
width: 100;
justify-content: end;
gap: 2rem;
padding: 0 1rem;
flex-direction: row;
li
list-style: none;
transition: transform 500ms;
:hover
transform: translateY(-10px);
a
text-decoration: none;
transition: color 300ms, transform 500ms;
color: var(--white);
:hover
color: var(--light-grey);
@media (max-width: 768px)
flex-direction: column;
position: fixed;
width: 100%;
justify-content: flex-start;
padding-top: 10vh;
background-color: var(--black);
transition: all 0.3s ease-in;
top: 6.5vh;
right: $(open) => open ? "0" : "-100%";
ul
flex-direction: column;
`
const LogoStyle = styled.div`
margin-left: 2.5rem;
a
text-decoration: none;
white-space: nowrap;
font-size: 1.65rem;
@media (min-width: 768px)
white-space: nowrap;
`;
const Hamburger = styled.div`
background-color: #111;
width: 30px;
height: 3px;
transition: all .3s linear;
align-self: center;
position: relative;
transform: $(open) => open ? "rotate(-45deg)" : "inherit";
::before,
::after
width: 30px;
height: 3px;
background-color: #111;
content: "";
position: absolute;
transition: all 0.3s linear;
::before
transform: $(open) => open ? "rotate(-90deg) translate(-10px, 0px)" : "rotate(0deg)";
top: -10px;
::after
opacity: $(open) => open ? "0" : "1";
transform: $(open) => open ? "rotate(90deg) " : "rotate(0deg)";
top: 10px;
`
const Navbar = () =>
const [navbarOpen, setNavbarOpen] = useState(false);
const [background, setBackground] = useState(false);
const changeBackground = () =>
if (window.scrollY > 25)
setBackground(true);
else
setBackground(false);
const toggleNavbar = () => setNavbarOpen(open => !open);
useEffect(() =>
window.addEventListener('scroll', changeBackground);
console.log(background);
return () =>
window.removeEventListener('scroll', changeBackground)
,[background]);
return (
<Navigation background=background>
<LogoStyle>
<Link to="/">Performant Web Design</Link>
</LogoStyle>
<Toggle
onClick= toggleNavbar()
>
<Hamburger open=navbarOpen />
</Toggle>
<Navbox open=navbarOpen>
<ul>
<li>
<Link to='/services'>Services</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/contact">Contact</Link>
</li>
</ul>
</Navbox>
</Navigation>
)
export default Navbar
【问题讨论】:
【参考方案1】:默认情况下,当导航到另一个页面时,状态应该被重置。 Link
中的 onClick
不会产生任何效果,因为它不是组件接受的道具(它不是你的组件,而是 Gatsby 的)。尝试在那里调试,因为所有解决方案都会弄脏代码,因为它应该是默认行为。
与此同时,您可以做的是在您的<li>
中拦截该点击
const handleClick=(to)=>
setNavbarOpen(false);
navigate(to);
<li onClick=handleClick('/services')>
<span>Services</span>
</li>
注意:这应该是一个临时解决方案,当您找到不稳定状态的原因时
按照你说的让它变得更好,你可以重构这个:
const closeNav = () =>
if (navbarOpen)
setNavbarOpen(false)
const openNav = () =>
if (!navbarOpen)
setNavbarOpen(true)
进入这个:
const toggleNavbar = () => setNavbarOpen(!navbarOpen)
还有这个:
navbarOpen ? <Hamburger open /> : <Hamburger />
进入这个:
<Hamburger open=navbarOpen />
还有这个:
navbarOpen ? (
<Navbox>
<ul>
<li>
<Link to="/services" >Services</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/contact">Contact</Link>
</li>
</ul>
<IconComponent />
</Navbox>
) : (
<Navbox open>
<ul>
<li>
<Link to="/services" onClick=closeNav>Services</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/contact">Contact</Link>
</li>
</ul>
</Navbox>
)
就这样吧:
<Navbox open=navbarOpen>
<ul>
<li>
<Link to="/services" onClick=closeNav>Services</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/contact">Contact</Link>
</li>
</ul>
</Navbox>
)
我将帮助您更好地调试(除其他外)。
【讨论】:
感谢您的帮助,是的,折射器确实有效,我稍微清理了样式。但是是的,在代码链接中遇到了与以前相同的问题。它适用于普通的 标签。导航方法确实改变了页面,并且快速加载的体验也在那里,但是菜单栏仍然存在问题。这有点奇怪,因为当 navbarOpen 状态为 false 时,组件应该会发生变化。我不知道该怎么做,我被困在这个问题上很长时间了。如果我也向您展示样式化的组件会有帮助吗? 当然。如果可以的话,尝试分享一个代码框,在那里提供帮助比猜测或查看部分代码要快 我可以给你一个我的 github 的链接吗?代码沙箱不工作。不知道是不是因为我有跨环境作为使用 ES6 模块而不是 commonJS 的依赖项 尝试尽可能多地分享信息,但请记住,这不是一个按需平台,克隆项目比在沙箱中实时定制项目要慢。它与常规的<a>
一起工作,因为它刷新了页面(在 React 的范围之外),因此您再次渲染所有内容,因此状态被重置。使用 Gatsby 的路由器,您只需刷新所需的部分(状态不同的部分),这就是为什么我建议使用 CodeSandbox 来检查所有设置的情况。您是否尝试过“肮脏的方法”? (只是为了检查它是否有效)
该解决方案的行为实际上是相同的,感谢您向我展示这种方式,因为我在导航功能上阅读了更多文档。现在我遇到了一个问题,因为 react 说我的导航栏组件正在无限循环中重新渲染。我在一个变量上使用了 useRef(true) 来查看它是否会从循环中逃脱,但不确定为什么现在会导致这种情况。大声笑我创建了一个全新的问题 OP 注释将包含来自导航栏组件的代码以上是关于Gatsbyjs 中的自定义导航栏的主要内容,如果未能解决你的问题,请参考以下文章