Путь к панели навигации не отображается должным образом при изменении страницы?

#reactjs #gatsby

#reactjs #gatsby

Вопрос:

Итак, я пытаюсь обновить фон панели навигации в зависимости от страницы, на которой я нахожусь, но когда я консолью.войдите в window.location.pathname систему, он не отображает путь должным образом.

Вот моя функция для изменения состояния панели навигации на основе имени пути

 const [navbar, setNavbar] = useState(false)

const updateNavbar = () => {
    if (window.location.pathname !== "/") {
        setNavbar(true)
    } else {
        setNavbar(false)
    }

    console.log(window.location.pathname)
}
  

Вот мой стилизованный компонент

 const Nav = styled.nav`
background: ${({ navbar }) => (navbar ? "red" : "blue")};
  

Затем я передаю это в свой JSX

 <Nav navbar={navbar}>
{menuData.map((item, index) => (
    <NavLink to={item.link} key={index} onClick={updateNavbar}>
      {item.title}
    </NavLink>
))}
  

Проблема в том, что если я нажимаю на пункт меню «О программе», в консоли отображается

 /
 
  

затем, если я снова нажму about , он покажет

 /about
  

Поэтому, когда я нажимаю about , страница визуально меняется на моем экране, но консоль регистрируется / , поэтому, чтобы панель навигации меняла цвета, я должен щелкнуть about еще раз, что не имеет смысла. Мне в значительной степени приходится дважды щелкнуть по нему, чтобы обновить цвет.

Почему не открывается окно.Расположение.имя пути автоматически обновляется на странице, на которой я нахожусь, вместо отображения предыдущей ссылки, которую я нажал, и только после повторного нажатия на ссылку отображается правильный путь?

Кроме того, я использую Gatsby JS и имею анимацию AOS, но я не думаю, что это имеет значение.

Обновление: если я передаю его в useEffect хук, он отображается / тогда /about , но почему он не показывает только меня /about , а не показывает как предыдущую, так и новую ссылку, которую я нажал?

 useEffect(() => {
    updateNavbar()
}, [])
  

Комментарии:

1. у gatsby есть маршрутизатор, тогда вам следует прочитать документы и использовать его вместо «внешнего источника»

Ответ №1:

Ваша консоль печатает перед отображением вашего маршрута!

Итак, вы можете использовать:

 setTimeout(function(){ console.log(window.location.pathname) }, 3000);
  

для печати или получения пути после изменения маршрута.

Комментарии:

1.это все равно не мешает ему отображаться дважды. Он все равно будет about about отображаться в консоли, за исключением задержки всего на 3 секунды

Ответ №2:

Я подозреваю, что код не работает, потому что вы настраиваете свою onClick функцию одновременно с переходом на другую страницу. Что может сработать для вас, может быть:

 const updateNavbar = (destination) => {
    if (typeof window !== 'undefined' amp;amp; window.location.pathname !== "/") {
        setNavbar(true)
        navigate("destination")
    } else if(typeof window !== 'undefined') {
        setNavbar(false)
        navigate("/")
    }

    console.log(window.location.pathname)
}

    <NavLink key={index} onClick={updateNavbar(item.link)}>
      {item.title}
    </NavLink>
  

По сути, вы препятствуете переходу кода на вашу страницу до того, как он установит состояние. Изменение встроенного to prop в navigate функцию.

Другим обходным путем, который может вам подойти, является использование состояния из <Link> компонента Gatsby:

 <Link
  to={`/your/page`}
  state={{ navbar: true }}
>
  

Вы можете получить значение, используя: props.location.state.navbar .

Я добавил его, чтобы дать вам подход. С другой стороны, приведенный выше код будет прерываться в режиме сборки ( gatsby build ), поскольку вы используете window (глобальный объект), и, поскольку gatsby build происходит на сервере, где нет окна, это приведет к прерыванию компиляции. Вы должны переносить каждое использование window inside:

 if (typeof window !== `undefined`) {
  // your stuff
}
  

Однако существует более собственный подход. Поскольку Gatsby расширяется от React (и от @react/router ), он предоставляет в компоненте верхнего уровня (pages) prop имя location со всей необходимой информацией. Конечно, вы можете передать обратную сторону от компонента страницы любому атомизированному компоненту, чтобы использовать его.


После некоторых проб и ошибок мы решили проблему с помощью:

 const updateNavbar = () => {
  if (window.location.pathname !== "/") {
    setNavbar(true)
 } else {
    setNavbar(false)
  }
}

useEffect(() => {
  if (window.location.pathname) {
    setNavbar(window.location.pathname)
}

console.log(window.location.pathname)
}, [])

background: ${({ navbar }) => (navbar != "/" ? "#000" : "transparent")};
  

Комментарии:

1. в нем говорится, что TypeError: не удается прочитать свойство ‘preventDefault’ из undefined. кроме того, что такое навигация в вашем коде?

2. Обновлено. navigate это вспомогательная функция, которая внутренне использует @reach/router (также известная как Gatsby и React) для навигации по страницам таким же образом, <Link> но с пользовательскими событиями (не щелчками). gatsbyjs.com/docs/gatsby-link /…

3. каким должен быть пункт назначения? в нем говорится, что ошибка «назначение» не определена. Кроме того, консоль. журнал ничего не показывает, когда я нажимаю на свои ссылки

4. Конечно, это не так, вы должны передать свое назначение, как вы это делали в to prop. Так и должно быть item.link . Проверьте косую черту в начале item.link .

5. он по-прежнему выполняет то же самое, что и моя исходная функция выше. кроме того, я не могу использовать item.link, потому что у меня есть отдельный компонент button вне файла данных, который также должен обновлять состояние и изменять панель навигации, поэтому item не определен для этой кнопки. Кроме того, почему вы не используете useEffect()?