如何在nextjs中获取上一个网址

kka*_*gil 10 next.js

如何在nextjs中获取以前的网址?我认为 values ,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
  }
}
Run Code Online (Sandbox Code Playgroud)

我该如何解决?或如何在登录后获取以前的 url 以移动页面?

Ema*_*uel 17

我已经使用 Context 做到了这一点

_app.tsx中

import { HistoryProvider } from '../contexts/History'

const MyApp: React.FC<AppProps> = ({ Component, pageProps }) => {
  return (
    <ThemeProvider theme={theme}>
      <Header />
        <HistoryProvider>
          <Component {...pageProps} />
        </HistoryProvider>...
Run Code Online (Sandbox Code Playgroud)

/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)

        // if you want to pop history on back
        const newHistory = history.slice(0, i)
        setHistory(newHistory)

        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
}
Run Code Online (Sandbox Code Playgroud)

任何组件中,您都可以使用

import { useHistory } from '../../contexts/History'

const ContentHeader: React.FC<ContentHeaderProps> = ({ title, hideBack }) => {
    const { history, back } = useHistory() ...
Run Code Online (Sandbox Code Playgroud)

我使用此组件来支持历史记录,忽略带有哈希 (#) 的链接,因为当我必须将页面滚动到某些页面 id 时,本机router.back()<a href="#someid" />会出现问题,我想返回到最后一页,而不是最后一页锚

编辑 01/04/2021

您还可以设置“后退”的后备路线。

back(fallbackRoute?: string): void

function back(fallbackRoute?: string) {
  for (let i = history.length - 2; i >= 0; i--) {
    const route = history[i]
    console.log({ route, pathname })
    if (!route.includes('#') && route !== pathname) {
      push(route)
      const newHistory = history.slice(0, i)
      setHistory(newHistory)
      return
    }
  }
  if (fallbackRoute) {
    router.push(fallbackRoute)
  }
}
Run Code Online (Sandbox Code Playgroud)


小智 11

您可以在getServerSideprops或任何其他数据获取方法的上下文中找到 Referer(因此是之前的 URL)

作为

    context.req.headers.referer  
Run Code Online (Sandbox Code Playgroud)

代码示例

    export async function getServerSideProps(context) {
      console.log(context.req.headers.referer)
    }
Run Code Online (Sandbox Code Playgroud)

  • 为了节省一些往返时间 - 它确实是“推荐人”,中间有一个 r,而不是两个 (7认同)

iur*_*rii 10

我认为你可以在全局状态下实现自定义历史记录

像这样的东西

_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;
Run Code Online (Sandbox Code Playgroud)

这样你就可以在你的组件中导航到历史记录中你想要的任何地方

if (!history || !history.length) {
    router.push('/');
} else {
    router.push(history[history.length - 1]);
}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!