Как получить предыдущий URL-адрес в React Gatsby

Я довольно хорошо знаком с React.js, но плохо знаком с Gatsby.

Я хочу определить URL предыдущей страницы в Gatsby?


person Profer    schedule 01.03.2019    source источник


Ответы (4)


Вы можете передать состояние вниз с помощью компонента Link:

import React from 'react';
import { Link } from 'gatsby';

const PrevPage = () => (
  <div>
    <Link
      to={`/nextpage`}
      state={{ prevPath: location.pathname }}
    >
      Next Page
    </Link>
  </div>
)

const NextPage = (props) => (
  <div>
    <p>previous path is: {props.location.state.prevPath}</p>
  </div>
);

Тогда у вас будет доступ к prevPath из this.props.location.state на следующей странице.

person Soroush Chehresa    schedule 01.03.2019
comment
Спасибо!!! Невозможно сделать это с помощью Гэтсби, поэтому я воспользуюсь вашим ответом выше - person Profer; 02.03.2019
comment
@Profer Не упоминайте об этом;) - person Soroush Chehresa; 02.03.2019
comment
@Profer Почему ты говоришь, что с Гэтсби этого не сделать? В этом ответе показано, как это сделать с помощью компонента Gatsby Link (который основан на компоненте Reach Router Link). - person coreyward; 03.03.2019
comment
@coreyward, потому что приведенный выше ответ - всего лишь уловка. Если есть способ, то сам Гэтсби предоставит некую опору или константу. - person Profer; 03.03.2019
comment
@Profer Как это уловка? Сам Gatsby предоставляет опору state для Link и передает значение, переданное ему компоненту страницы следующей страницы. Это задокументировано здесь. < / а>. - person coreyward; 04.03.2019
comment
@coreyward правильный. Передача состояния в компонент Link - это функция Gatsby Link, которая расширена из API-интерфейса досягаемости / маршрутизатора. - person Vien Tang; 11.03.2019
comment
Это неверно ... location.state сохраняется ... поэтому, когда вы переходите на эту страницу, это состояние будет установлено правильно, но затем, если вы перейдете на другую страницу и вернете браузер, состояние будет иметь то же значение, которое является ложным. - person itdoesntwork; 23.10.2019

Полный кредит на ответ @ soroushchehresa - этот ответ - просто дополнения, построенные на нем.

Gatsby выдаст ошибку во время производственной сборки, поскольку location недоступен во время рендеринга на стороне сервера. Вы можете обойти это, проверив сначала объект window:

class Page extends React.Component {
  state = {
    currentUrl: '',
  }

  componentDidMount() {
    if (typeof window == 'undefined') return
    this.setState({ currentUrl: window.location.href })
  }

  render() {
    return (
      <Link to="..." state={{ prevUrl: this.state.currentUrl }}>
    )
  }
}

Но это требует, чтобы мы реализовали это на каждой странице, что утомительно. Гэтсби уже настроил @reach/router для рендеринга на стороне сервера, поэтому мы можем подключиться к его location реквизитам. Только компоненты маршрутизатора получают эти реквизиты, но мы можем использовать компонент Location @reach/router, чтобы передать его другим компонентам.

При этом мы можем написать настраиваемый компонент Link, который всегда передает предыдущий URL в своем состоянии:

// ./src/components/link-with-prev-url.js

import React from 'react'
import { Location } from '@reach/router'
import { Link } from 'gatsby'

const LinkWithPrevUrl = ({ children, state, ...rest }) => (
  <Location>
    {({ location }) => (
                      //make sure user's state is not overwritten
      <Link {...rest} state={{ prevUrl: location.href, ...state}}>
        { children }
      </Link>
    )}
  </Location>
)

export { LinkWithPrevUrl as Link }

Затем мы можем импортировать наш пользовательский компонент Link вместо Gatsby's Link:

-  import { Link } from 'gatsby'
+  import { Link } from './link-with-prev-url'

Теперь каждый компонент страницы Gatsby получит следующие реквизиты URL:

const SomePage = ({ location }) => (
  <div>previous path is {location.state.prevUrl}</div>
);

Вы также можете подумать о создании контейнера, в котором хранится состояние для клиентской стороны, и использовать _11 _ или wrapPageElement как в gatsby-ssr.js, так и gatsby-browser.js.

person Derek Nguyen    schedule 01.03.2019
comment
Slick. Мне это нравится. - person coreyward; 04.03.2019
comment
На самом деле я натолкнулся на первоначальный ответ в документации Гэтсби и надеялся избежать скуки. Спасибо за разъяснение для создания оптимизированного подхода - отличная идея! Я смотрел на onRouteUpdate API в gatsby-browser.js, который предоставляет location, prevLocation, но, насколько я могу судить, он делает их доступными только для использования вне рамок моих компонентов Gatsby / React. - person Victor; 04.03.2019

Эти ответы частично верны. Если вы устанавливаете состояние с помощью link api, то состояние сохраняется в истории браузера.

Итак, если вы перейдете с Page1 на Page2, то, например, state.prevUrl будет правильно установлен на Page1.

Но если вы перейдете к Page3 из Page2, а затем откроете браузер, то state.prevUrl все равно будет Page1, что неверно.

Лучший способ, который я нашел, - это добавить что-то подобное в файл gatsby-browser.js.

export const onRouteUpdate = ({ location, prevLocation }) => {
  if (location && location.state)
    location.state.referrer = prevLocation ? prevLocation.pathname : null
}

таким образом у вас всегда будет предыдущий URL-адрес, доступный на месте.

person itdoesntwork    schedule 23.10.2019