如何在反应盖茨比中获得以前的 url
How to get previous url in react gatsby
我对 React.js
非常熟悉,但对 Gatsby
很陌生。
我想检测 Gatsby
中的上一页 URL?
您可以使用 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>
);
然后您可以从下一页的 this.props.location.state
访问 prevPath
。
完全归功于 — 这个答案只是建立在它之上的额外内容。
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 }}>
)
}
}
但这需要我们在每个页面上都实现这个,这很繁琐。 Gatsby 已经为服务器端渲染设置了 @reach/router
,所以我们可以挂钩它的 location
属性。只有路由器组件才能获得该道具,但我们可以使用 @reach/router
's Location
组件将其传递给其他组件。
有了它,我们可以编写一个自定义的 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 的 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>
);
您还可以考虑创建一个存储客户端状态的容器,并在 gatsby-ssr.js
和 gatsby-browser.js
中使用 wrapRootElement
or wrapPageElement
。
这些答案部分正确。如果您使用 link api 设置状态,则该状态会保留在浏览器历史记录中。
因此,如果您从 Page1
转到 Page2
,那么 state.prevUrl
将正确设置为 Page1
但是,如果您从 Page2
转到 Page3
,然后返回浏览器,那么 state.prevUrl
仍然是 Page1
,这是错误的。
我发现处理此问题的最佳方法是在 gatsby-browser.js
上添加类似的内容
export const onRouteUpdate = ({ location, prevLocation }) => {
if (location && location.state)
location.state.referrer = prevLocation ? prevLocation.pathname : null
}
这样一来,您将始终可以在现场使用以前的 url。
我用下面的代码解决了我的问题。这是参考 link https://github.com/gatsbyjs/gatsby/issues/10410
// gatsby-browser.js
exports.onRouteUpdate = () => {
window.locations = window.locations || [document.referrer]
locations.push(window.location.href)
window.previousPath = locations[locations.length - 2]
}
现在您可以获得 previousPath
可以从任何地方访问。
我对 React.js
非常熟悉,但对 Gatsby
很陌生。
我想检测 Gatsby
中的上一页 URL?
您可以使用 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>
);
然后您可以从下一页的 this.props.location.state
访问 prevPath
。
完全归功于
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 }}>
)
}
}
但这需要我们在每个页面上都实现这个,这很繁琐。 Gatsby 已经为服务器端渲染设置了 @reach/router
,所以我们可以挂钩它的 location
属性。只有路由器组件才能获得该道具,但我们可以使用 @reach/router
's Location
组件将其传递给其他组件。
有了它,我们可以编写一个自定义的 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 的 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>
);
您还可以考虑创建一个存储客户端状态的容器,并在 gatsby-ssr.js
和 gatsby-browser.js
中使用 wrapRootElement
or wrapPageElement
。
这些答案部分正确。如果您使用 link api 设置状态,则该状态会保留在浏览器历史记录中。
因此,如果您从 Page1
转到 Page2
,那么 state.prevUrl
将正确设置为 Page1
但是,如果您从 Page2
转到 Page3
,然后返回浏览器,那么 state.prevUrl
仍然是 Page1
,这是错误的。
我发现处理此问题的最佳方法是在 gatsby-browser.js
上添加类似的内容export const onRouteUpdate = ({ location, prevLocation }) => {
if (location && location.state)
location.state.referrer = prevLocation ? prevLocation.pathname : null
}
这样一来,您将始终可以在现场使用以前的 url。
我用下面的代码解决了我的问题。这是参考 link https://github.com/gatsbyjs/gatsby/issues/10410
// gatsby-browser.js
exports.onRouteUpdate = () => {
window.locations = window.locations || [document.referrer]
locations.push(window.location.href)
window.previousPath = locations[locations.length - 2]
}
现在您可以获得 previousPath
可以从任何地方访问。