TypeError: Невозможно прочитать свойство 'choice' из null в состоянии ссылки Гэтсби - PullRequest
0 голосов
/ 10 апреля 2019

Im Пытаюсь добавить некоторые ClassName, когда я нажимаю на подменю из выпадающего меню. Это то, как выглядит панель навигации https://imgur.com/9iCDj7k

Код работал раньше, но после перезапуска разработки gatsby выдает ошибку TypeError.: Невозможно прочитать свойство 'choice', равное null

, эта панель навигации является Компонентом, поэтому она всегда загружается на каждой странице

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 я поместилимя состояния родительской навигации, поэтому, когда я нажимаю суб-навигацию, появляется троичный оператор, который добавил активный стиль

, я не использую ActiveClassName или PartiallyActive, потому что я хочу, когда я щелкаю по подменю в Convention,Стиль конвенции изменился.

1 Ответ

0 голосов
/ 11 апреля 2019

Я вижу, вы установили здесь состояние:

<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'}`} />
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...