如何在React Gatsby中获取先前的URL

Pro*_*fer 3 javascript static-site reactjs gatsby

我用非常熟悉的React.js,但新Gatsby

我要在中检测上一页URL Gatsby

itd*_*ork 9

这些答案部分正确。如果您使用链接 api 设置状态,则该状态会保留在浏览器历史记录中。

因此,如果您从Page1to 开始,Page2则 egstate.prevUrl将正确设置为Page1

但是如果你去Page3Page2然后做一个浏览器,那么它state.prevUrl仍然Page1是错误的。

我发现处理这个问题的最好方法是在 gatsby-browser.js 上添加这样的东西

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

这样,您将始终可以在位置上找到以前的网址。


Sor*_*esa 8

您可以使用以下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>
);
Run Code Online (Sandbox Code Playgroud)

然后,您可以prevPaththis.props.location.state下一页访问。


Der*_*yen 5

完全归功于@soroushchehresa的答案 -此答案只是基于此的其他内容。

由于location在服务器端渲染期间不可用,因此Gatsby将在生产构建期间引发错误。您可以通过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 }}>
    )
  }
}

Run Code Online (Sandbox Code Playgroud)

但这需要我们在每个页面上实现,这很繁琐。Gatsby已经@reach/router为服务器端渲染进行了设置,因此我们可以使用它的location道具。只有路由器组件才能获得该道具,但是我们可以使用@reach/routerLocation组件将其传递给其他组件。

这样,我们可以编写一个自定义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 }
Run Code Online (Sandbox Code Playgroud)

然后,我们可以导入自定义Link组件而不是Gatsby的Link:

-  import { Link } from 'gatsby'
+  import { Link } from './link-with-prev-url'
Run Code Online (Sandbox Code Playgroud)

现在,每个Gatsby页面组件将获得以下先前的url属性:

const SomePage = ({ location }) => (
  <div>previous path is {location.state.prevUrl}</div>
);
Run Code Online (Sandbox Code Playgroud)

你也可以考虑创建一个容器,储存状态的客户端和使用wrapRootElement或者wrapPageElement在这两个gatsby-ssr.jsgatsby-browser.js

  • 感谢您的关注和完成:) (2认同)
  • 光滑 我喜欢。 (2认同)
  • 实际上,我是通过Gatsby文档找到了最初的答案,并希望避开繁琐的工作。感谢您对它的阐述以创建一种简化的方法-伟大的想法!我正在看gatsby-browser.js中的`onRouteUpdate` API,该API公开了`location,prevLocation`,但是据我所知,它只能使它们在我的Gatsby / React组件范围之外可用。 (2认同)