разрешить компоненту обнаруживать изменение маршрута в Гэтсби - PullRequest
0 голосов
/ 17 апреля 2020

В проекте Gatsby у меня есть компонент заголовка, который сохраняется на каждой странице. В заголовке есть модал для отображения навигации. Мне нужно установить состояние isOpen в false при каждом изменении маршрута, чтобы мод Нав закрывался. Поскольку маршрут может меняться не только путем нажатия на ссылки в модальном режиме, но и с помощью кнопки «Назад» в браузере, я не хочу использовать событие для ссылки, чтобы закрыть модальное окно.

В Гэтсби я могу использовать onRouteUpdate в gatsby-browser. js для обнаружения изменений маршрута, и это хорошо работает. Но мне нужно передать событие моему компоненту, и именно здесь я испытываю трудности. Я упростил приведенный ниже код, чтобы показать настройки.

gatsby-browser. js:

import React from "react"
import Layout from "./src/components/layout"

export const wrapPageElement = ({ element, props }) => {
  return <Layout {...props}>{element}</Layout>
}

export const onRouteUpdate = () => {
  console.log("onRouteUpdate") // this works
}

layout. js:

import React from "react"

import Header from "./header"
import Footer from "./footer"

const Layout = ({ children }) => (
    <>
      <Header />
      <main>
        {children}
      </main>
      <Footer />
    </>
  )

export default Layout

header . js:

import React, { useState } from "react"

const Header = () => {
  const [isOpen, setIsOpen] = useState(null)
  const toggleState = ({ props }) => {
    let status
    if (props) status = props.status
    else status = !isOpen
    setIsOpen(status)
  }
  return (
    <header>
      <div>This is the header</div>
      <button onClick={toggleState}>Toggle Open/Close</button>
      <button onClick={toggleState({ status: false })}>This will always close</button>
      /* logic here uses isOpen state to determine display */
    </header>
  )
}

export default Header

1 Ответ

1 голос
/ 17 апреля 2020

Я пришел к решению своего вопроса, поэтому подумал, что поделюсь. Любые комментарии / улучшения всегда приветствуются.

Во-первых, нам не нужно использовать «onRouteUpdate» в gatsby-broser. js, поэтому давайте удалим это:

/* gatsby-browser.js */
import React from "react"
import Layout from "./src/components/layout"

export const wrapPageElement = ({ element, props }) => {
  return <Layout {...props}>{element}</Layout>
}

Затем, в layout. js убедитесь, что передали местоположение заголовку:

/* layout.js */
import React from "react"

import Header from "./header"
import Footer from "./footer"

const Layout = ({ children, location }) => (
    <>
      <Header location={location} />
      <main>
        {children}
      </main>
      <Footer />
    </>
  )

export default Layout

Наконец, в заголовке. js местоположение сохраняется в ссылке на элемент заголовка с использованием хука useRef. Хук useEffect будет срабатывать при изменении маршрута, поэтому мы можем использовать его для сравнения:

/* header.js */
import React, { useState, useEffect, useRef } from "react"

const Header = () => {
  const [isOpen, setIsOpen] = useState(null)
  const myRef = useRef({
    location: null,
  })
  useEffect(() => {
    // set the location on initial load
    if (!myRef.current.location) myRef.current.location = location
    // then make sure dialog is closed on route change
    else if (myRef.current.location !== location) {
      if (isOpen) toggleState({ status: false })
      myRef.current.location = location
    }
  })
  const toggleState = ({ props }) => {
    let status
    if (props) status = props.status
    else status = !isOpen
    setIsOpen(status)
  }
  return (
    <header ref={myRef}>
      <div>This is the header</div>
      <button onClick={toggleState}>Toggle Open/Close</button>
      <button onClick={toggleState({ status: false })}>This will always close</button>
    </header>
  )
}

export default Header

Надеюсь, это поможет любому, кто ищет подобную функциональность.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...