我试图从下拉导航栏中单击子菜单时添加一些ClassName 这就是导航栏的样子 https://imgur.com/9iCDj7k
该代码在启动gatsby开发之前有效,但是在重新启动gatsby开发之后却显示错误TypeError:无法读取null的'choice'属性
此导航栏是一个组件,因此始终在每个页面上加载
import React from "react"
import { Link } from "gatsby"
const Navbar = () => {
return (
<div
className="collapse navbar-collapse" id="navbarSupportedContent">
<ul className="navbar-nav mr-auto justify-content-around w-100">
<li className="nav-item"><Link className="nav-link pb-md-3" activeClassName="nav-link-active" to="/">Home</Link></li>
<li className="nav-item">
<div className={window.history.state.choice === 'Convention' ? 'dropdown nav-link pb-md-3 active' : 'dropdown nav-link pb-md-3'}>
<div className="dropdown-toggle" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Convention</div>
<div className="dropdown-menu" aria-labelledby="dropdownMenuButton"><Link className="dropdown-item" activeClassName="nav-sub-active" to="/convention/general-information" state={{ choice: 'Convention' }}>General Information</Link><Link className="dropdown-item" href="/coming-soon">Plenary & Special Sessions</Link><Link className="dropdown-item" href="/coming-soon">Technology Session</Link>
<div
className="dropdown-toggle dropdown-item nested-dropitem" id="dropdownMenu1Button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Technical Program</div>
<div className="dropright">
<div className="dropdown-menu" aria-labelledby="dropdownMenuButton1"><Link className="dropdown-item" href="/coming-soon">Oral Presentation</Link><Link className="dropdown-item" href="/coming-soon">Poster Presentation</Link></div>
</div><Link className="dropdown-item" href="/coming-soon">Download Full Paper</Link><Link className="dropdown-item" href="/coming-soon">Registration</Link></div>
</div>
</li>
<li className="nav-item">
<div className={window.history.state.choice === 'Exhibition' ? 'dropdown nav-link pb-md-3 active' : 'dropdown nav-link pb-md-3'}>
<div className="dropdown-toggle" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Exhibition</div>
<div className="dropdown-menu" aria-labelledby="dropdownMenuButton"><Link className="dropdown-item" to="/exhibition/why-exhibit" state={{ choice: 'Exhibition' }}>Why Exhibit?</Link><Link className="dropdown-item" to="/exhibition/book-your-space" state={{ choice: 'Exhibition' }}>Book Your Space</Link><Link className="dropdown-item" href="/coming-soon">Exhibitor Services</Link>
<Link
className="dropdown-item" to="/exhibition/about-the-venue" state={{ choice: 'Exhibition' }}>About the Venue</Link>
</div>
</div>
</li>
就像你们看到的那样,在Subnav链接上,我放置了父导航的状态名称,因此,当我单击sub nav时,有三元运算符添加了活动样式
我不使用ActiveClassName或PartiallyActive,因为我想要的是当我单击Convention的子菜单时,Convention样式被更改了。
答案 0 :(得分:1)
根据文档:
gatsby-link,您应该可以使用location
来检索状态,但不幸的是,这对我也不起作用,并且会收到与您类似的错误。
我能够使用Link
从盖茨比window.history.state
检索状态
我在这里找到了答案:gatsby-issue#9091
答案 1 :(得分:0)
我看到您在这里设置状态
<Link
className="dropdown-item"
to="/exhibition/about-the-venue"
state={{ choice: 'Exhibition' }}>
About the Venue
</Link>
但是window.history.state
仅在用户已经单击链接时填充。因此,在第一次加载时,它不会存在。另外,在gatsby build
期间您可能会遇到问题,因为window
对象在那里不可用。
您可以添加一个空检查:
const getHistoryState = (prop) => {
if (typeof window === 'undefined') return
if (!window.history.state) return
return window.history.state[prop]
}
<div className={`dropdown nav-link pb-md-3 ${getHistoryState(choice) === 'Exhibition' && 'active'}`}>
或全局设置该属性:
// gatsby-browser.js
export const onClientEntry = () => {
window.history.pushState({ choice: '...' }, '')
}
不过,在组件中使用window.history...
之前,您仍然需要检查窗口。
为避免完全检查窗口,请使用location
传递给页面组件的reach-router
对象,例如:
// src/index.js
export default const IndexPage = ({ location }) => (
<NavBar location={location} />
)
// NavBar.js
const NavBar = ({ location }) => (
<div className={`class name here ${location.state && location.state.choice && 'active'}`} />
)