Html Next.js 从/重定向到另一个页面

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/58173809/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 18:02:55  来源:igfitidea点击:

Next.js Redirect from / to another page

htmlreactjsroutingreact-routernext.js

提问by Arthur

I'm new in Next.jsand I'm wondering how to redirect from start page ( /) to /hello-nextjsfor example. Once user loads a page and after that determine if path === /redirect to /hello-nextjs

我是Next.js 的新手,我想知道如何从起始页 ( /)重定向到/hello-nextjs例如。一旦用户加载页面,然后确定路径 === /重定向到/hello-nextjs

In react-routerwe do something like:

react-router 中,我们执行以下操作:

<Switch>
  <Route path="/hello-nextjs" exact component={HelloNextjs} />
  <Redirect to="/hello-nextjs" /> // or <Route path="/" exact render={() => <Redirect to="/hello-nextjs" />} />
</Switch>

回答by Nico

In next.jsyou can redirect after the page is loadedusing Routerex :

next.js您可以使用ex加载页面后重定向Router

import Router from 'next/router'

componentDidMount(){
    const {pathname} = Router
    if(pathname == '/' ){
       Router.push('/hello-nextjs')
    }
}

Or with Hooks :

或者使用钩子:

import React, { useEffect } from "react";
...
useEffect(() => {
   const {pathname} = Router
   if(pathname == '/' ){
       Router.push('/hello-nextjs')
   }
 });

回答by Afsanefda

There are three approaches.

有三种方法。

1.Redirect on events or functions:

1.重定向事件或函数:

import Router from 'next/router';

<button type="button" onClick={() => Router.push('/myroute')} />

2.Redirect with hooks:

2.使用钩子重定向:

import Router , {useRouter}  from 'next/router';

const router = useRouter()

<button type="button" onClick={() => router.push('/myroute')} />

3.Redirect with Link:

3.使用链接重定向:

based on Nextjs docs the <a>tag is neccessary inside the link for things like open in a new tab!

基于 Nextjs 文档,<a>链接内的标签是必需的,例如在新标签页中打开!

import Link from 'next/link';

<Link href="/myroute">
   <a>myroute</a>
</Link>

There are some other options for serverside routing which is asPath. in all described approaches you can add asPath to redirect both client and server side.

服务器端路由还有一些其他选项,即asPath. 在所有描述的方法中,您可以添加 asPath 来重定向客户端和服务器端。

回答by Tessaracter

@Nico's answer solves the issue when you are using classes.

@Nico 的回答解决了您使用课程时的问题。

If you are using function you cannot use componentDidMount. Instead you can use React Hooks useEffect.

如果您正在使用函数,则不能使用componentDidMount. 相反,您可以使用 React Hooks useEffect


import React, {useEffect} from 'react';

export default function App() {
  const classes = useStyles();

  useEffect(() => { 
    const {pathname} = Router
    if(pathname == '/' ){
      Router.push('/templates/mainpage1')
    }  
  }
  , []);
  return (
    null
  )
}

In 2019 React introducedhooks. which are much faster and efficient than classes.

2019 年,React引入了钩子。这比类更快、更有效。

回答by Eric Burel

Semi-official example

半官方示例

The with-cookie-authexamples redirect in getInitialProps. I am not sure whether it's a valid pattern or not yet, but here's the code:

with-cookie-auth实例重定向getInitialProps。我不确定它是否是有效模式,但这是代码:

Profile.getInitialProps = async ctx => {
  const { token } = nextCookie(ctx)
  const apiUrl = getHost(ctx.req) + '/api/profile'

  const redirectOnError = () =>
    typeof window !== 'undefined'
      ? Router.push('/login')
      : ctx.res.writeHead(302, { Location: '/login' }).end()

  try {
    const response = await fetch(apiUrl, {
      credentials: 'include',
      headers: {
        Authorization: JSON.stringify({ token }),
      },
    })

    if (response.ok) {
      const js = await response.json()
      console.log('js', js)
      return js
    } else {
      // https://github.com/developit/unfetch#caveats
      return await redirectOnError()
    }
  } catch (error) {
    // Implementation or Network error
    return redirectOnError()
  }
}

It handles both server side and client side. The fetchcall is the one that actually get the auth token, you might want to encapsulate this into a separate function.

它处理服务器端和客户端。fetch调用是实际获取身份验证令牌的调用,您可能希望将其封装到一个单独的函数中。

What I would advise instead

我会建议什么

?1. 在服务器端渲染时重定向(在 SSR 期间避免 flash)

This is the most common case. You want to redirect at this point to avoid the initial page flashing on first load.

这是最常见的情况。此时您想重定向以避免初始页面在首次加载时闪烁。

MyApp.getInitialProps = async appContext => {
    const currentUser = await getCurrentUser(); // define this beforehand
    const appProps = await App.getInitialProps(appContext);
    // check that we are in SSR mode (NOT static and NOT client-side)
    if (typeof window === "undefined" && appContext.ctx.res.writeHead) {
      if (!currentUser && !isPublicRoute(appContext.router.pathname)) {
          appContext.ctx.res.writeHead(302, { Location: "/account/login" });
          appContext.ctx.res.end();
      }
    }
    return { ...appProps, currentUser };
  };
?2. 在 componentDidMount 中重定向(当 SSR 被禁用时很有用,例如在静态模式下)

This is a fallback for client side rendering.

这是客户端渲染的回退。

  componentDidMount() {
    const { currentUser, router } = this.props;
    if (!currentUser && !isPublicRoute(router.pathname)) {
      Router.push("/account/login");
    }
  }

I could not avoid flashing the initial page in static mode add this point, because you can't redirect during the static build, but it seems better than the usual approaches. I'll try to edit as I make progress.

我无法避免在静态模式下闪烁初始页面添加这一点,因为您无法在静态构建期间重定向,但它似乎比通常的方法更好。我会在取得进展时尝试编辑。

Full example is here

完整的例子在这里

Relevant issue, which sadly ends up with a client only answer

相关问题,遗憾的是最终只有客户回答

回答by BruceHill

I have implemented this functionality in my Next.JSapp by defining a root page this does the redirect server side and client side. Here is the code for the root page:

我已经Next.JS通过定义一个根页面在我的应用程序中实现了这个功能,它执行重定向服务器端和客户端。这是根页面的代码:

import { useEffect } from "react";
import Router from "next/router";

const redirectTo = "/hello-nextjs";

const RootPage = () => {
  useEffect(() => Router.push(redirectTo));
  return null;
};
RootPage.getInitialProps = (ctx) => {
  if (ctx.req) {
    ctx.res.writeHead(302, { Location: redirectTo });
    ctx.res.end();
  }
};

export default RootPage;

回答by Arthur

redirect-to.ts

redirect-to.ts

import Router from "next/router";

export default function redirectTo(
  destination: any,
  { res, status }: any = {}
): void {
  if (res) {
    res.writeHead(status || 302, { Location: destination });
    res.end();
  } else if (destination[0] === "/" && destination[1] !== "/") {
    Router.push(destination);
  } else {
    window.location = destination;
  }
}

_app.tsx

_app.tsx

import App, {AppContext} from 'next/app'
import Router from "next/router"
import React from 'react'
import redirectTo from "../utils/redirect-to"


export default class MyApp extends App {
  public static async getInitialProps({Component, ctx}: AppContext): Promise<{pageProps: {}}> {
    let pageProps = {};

    if (Component.getInitialProps) {
      pageProps = await Component.getInitialProps(ctx);
    }

    if (ctx.pathname === "" || ctx.pathname === "/_error") {
      redirectTo("/hello-next-js", { res: ctx.res, status: 301 }); <== Redirect-To
      return {pageProps};
    }

    return {pageProps};
  }

  render() {
    const {Component, pageProps} = this.props;
    return <Component {...pageProps}/>
  }
}