如何在nextjs中获取以前的网址?
我认为值this.props.router.asPath
和nextProps.router.asPath
是不同的。
实际上,我想登录后router.push
。我知道router.back
转到上一页。但是也可以去其他站点。具有历史记录堆栈的用户转到上一页,没有历史记录堆栈的用户转到/
主页。
import { Component } from 'react'
import App, { Container } from 'next/app';
import ErrorComponent from '@/components/error'
export default class MyApp extends App {
render() {
console.log(this.props)
const { Component, pageProps, router } = this.props;
const props = {
...pageProps,
router
}
return (
<ErrorBoundary>
<Container>
<Component {...props} />
</Container>
</ErrorBoundary>
);
}
componentWillReceiveProps(nextProps) {
// previous page url /contents
console.log(this.props.router.asPath) // /about
console.log(nextProps.router.asPath) // /about
console.log('window.history.previous.href', window.history.previous) // undefined
}
}
我该如何解决?或登录后如何获取上一个URL来移动页面?
答案 0 :(得分:4)
您可以在getServerSideprops或任何其他数据获取方法的上下文中找到Referer(即上一个URL)
为
context.req.headers.referer
示例代码
export async function getServerSideProps(context) {
console.log(context.req.headers.referer)
}
答案 1 :(得分:1)
我认为您可以在全局状态下实现自定义历史记录
类似这样的东西
_app.js
import React from 'react';
import App, { Container } from 'next/app';
class MyApp extends App {
static async getInitialProps({ Component, ctx }) {
let pageProps = {};
if (Component.getInitialProps) {
pageProps = await Component.getInitialProps(ctx);
}
return { pageProps };
}
state = {
history: [] // keep history items in state
};
componentDidMount() {
const { asPath } = this.props.router;
// lets add initial route to `history`
this.setState(prevState => ({ history: [...prevState.history, asPath] }));
}
componentDidUpdate() {
const { history } = this.state;
const { asPath } = this.props.router;
// if current route (`asPath`) does not equal
// the latest item in the history,
// it is changed so lets save it
if (history[history.length - 1] !== asPath) {
this.setState(prevState => ({ history: [...prevState.history, asPath] }));
}
}
render() {
const { Component, pageProps } = this.props;
return (
<Container>
<Component history={this.state.history} {...pageProps} />
</Container>
);
}
}
export default MyApp;
因此,您可以在组件中浏览历史记录中的任何位置
if (!history || !history.length) {
router.push('/');
} else {
router.push(history[history.length - 1]);
}
希望这会有所帮助!
答案 2 :(得分:0)
我尝试做类似iurii
的回答。我的_app.js
看起来像这样(我试图与segment.com集成,因此感到有这种需要)
export default class MyApp extends App {
componentDidMount () {
const { asPath } = this.props.router;
this.setState(prevState => ({ history: [...prevState.history, asPath] }));
const isBrowser = typeof window !== 'undefined';
if(isBrowser) {
// For the first page load
console.log("Going to log first load --> referrer : ", document.referrer);
// this can get me the document.referrer properly, if I come to the website from a third party source like google search.
global.analytics.page(window.location.href,
{referrer: document.referrer}
)
}
}
static async getInitialProps ({ Component, router, ctx }) {
let pageProps = {}
if (Component.getInitialProps) {
pageProps = await Component.getInitialProps(ctx)
}
return { pageProps }
}
state = {
history: [] // keep history items in state
};
componentDidUpdate() {
const { history } = this.state;
const { asPath } = this.props.router;
// if current route (`asPath`) does not equal
// the latest item in the history,
// it is changed so lets save it
if (history[history.length - 1] !== asPath) {
global.analytics.page(window.location.href, {
referrer: history[history.length - 1] ? history[history.length - 1] : ""
})
// this simulates the document.referrer on pages after the user navigates
this.setState(prevState => ({ history: [...prevState.history, asPath] }));
}
}
因此,结合使用history[history.length - 1] ? history[history.length - 1] : ""
和const isBrowser = typeof window !== 'undefined';
,我可以在所有情况下模拟document.referrer。但是我想念一种情况,假设我在google,我的网站目标网页是A,那么A指向B
然后google to A
->我得到document.referrer
为google
然后A to B
->我得到document.referrer
为A
,与行为一致。
但是现在,如果我刷新页面B,则我的document.referrer
再次变为google
。
我认为我可以将最后一个已知的先前URL保存在本地存储中,但这将是一种反模式,因为浏览器的“后退”按钮可以正确地将用户带到上一页(A
),因此数据已经在那里。目前,我可以使用此解决方案,因为我仅将其用于segment.com和google Analytics(分析)目的,因此刷新将使我的分析数据有些混乱,但仍希望有一个完美的解决方案,以便获得准确的数据。
答案 3 :(得分:0)
我已经使用Context做这个
在 _app.tsx
import { HistoryProvider } from '../contexts/History'
const MyApp: React.FC<AppProps> = ({ Component, pageProps }) => {
return (
<ThemeProvider theme={theme}>
<Header />
<HistoryProvider>
<Component {...pageProps} />
</HistoryProvider>...
/contexts/History.tsx
import { useRouter } from 'next/router'
import React, { createContext, useState, useEffect, useContext } from 'react'
interface HValidation {
history: string[]
setHistory(data: string[]): void
back(): void
}
const HistoryContext = createContext<HValidation>({} as HValidation)
export const HistoryProvider: React.FC = ({ children }) => {
const { asPath, push, pathname } = useRouter()
const [history, setHistory] = useState<string[]>([])
function back() {
for (let i = history.length - 2; i >= 0; i--) {
const route = history[i]
if (!route.includes('#') && route !== pathname) {
push(route)
break
}
}
}
useEffect(() => {
setHistory(previous => [...previous, asPath])
}, [asPath])
return (
<HistoryContext.Provider
value={{
back,
history,
setHistory,
}}
>
{children}
</HistoryContext.Provider>
)
}
export function useHistory(): HValidation {
const context = useContext(HistoryContext)
return context
}
在任何组件中,您可以使用
import { useHistory } from '../../contexts/History'
const ContentHeader: React.FC<ContentHeaderProps> = ({ title, hideBack }) => {
const { history, back } = useHistory() ...
我已使用此组件来备份历史记录,而忽略带有哈希(#)的链接,因为当我不得不将页面滚动到某些页面ID时,本机 router.back()出现了错误。 我想回到最后一页,而不是最后一个锚点
答案 4 :(得分:0)