Next.js Перенаправлення з / на іншу сторінку


15

Я новачок у Next.js, і мені цікаво, як, наприклад, переадресувати з початкової сторінки ( / ) на / hello-nextjs . Як тільки користувач завантажує сторінку, а потім визначте, чи шлях === / перенаправлення до / hello-nextjs

У реактор-маршрутизаторі ми робимо щось на кшталт:

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

1
коли ви хочете, щоб переадресація відбулася?
Ніко

@ NicolòCozzani, як тільки користувач завантажує сторінку. Після цього визначте, чи URL-адреса === / переспрямувати на / hello-nextjs
Артур

Відповіді:


23

В той next.jsви можете перенаправити після завантаження сторінки , використовуючи Routerприклад:

import Router from 'next/router'

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

Або з гачками:

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

Як мені зробити гачки React ??
Tessaracter

Без використання занять
Tessaracter

2
Відповідь @Tessaracter оновлена
Ніко

2
А як щодо ССР? Початкова сторінка блимає таким підходом
Ерік Бурел

@EricBurel ОП чітко запитав "Як тільки користувач завантажує сторінку" btw перевірте це github.com/zeit/next.js/isissue/649
Ніко

16

Існує три підходи.

1.Редирект на події або функції:

import Router from 'next/router';

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

2.Перевірка з гачками:

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

const router = useRouter()

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

3.Редирект із посиланням:

на основі документів Nextjs потрібен <a>тег всередині посилання для таких речей, як відкрити в новій вкладці!

import Link from 'next/link';

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

Є деякі інші варіанти маршрутизації на сервері, яка є asPath. у всіх описаних підходах ви можете додати asPath для переадресації як з боку клієнта, так і з боку сервера.


Привіт! Ви можете подивитися на моє рішення
Артур

Це імперативний підхід. Добре перенаправляти на дії користувача, але не ґрунтуватися на умові завантаження сторінки, як зазначено в питанні.
Ерік Бурель

Я не зрозумів, що ти мав на увазі !?
Афсанефда

Питання стосується автоматичного переадресації залежно від поточної назви маршруту маршруту. Ваші відповіді в цьому контексті дійсні, але не піддаються застосуванню: всі вони потребують натискання користувача.
Ерік Бурель

@EricBurel, так, це не те, чого я хотів, ця відповідь не вирішує мого питання
Артур

3

@ Відповідь Ніко вирішує проблему під час занять.

Якщо ви використовуєте функцію, яку ви не можете використовувати 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
  )
}

У 2019 році React представив гачки. які набагато швидші та ефективніші, ніж заняття.


У цьому питанні описано, чого я хотів у результаті
Артур

@Arthur. О, але ваше запитання не говорить так. Відповідь @Nico та моя точно однакова і є заміною того, <Switch>що ви використовуєте React-router. Навіть <Switch>не надає жодного коду статусу 303, 302. Тільки переспрямовує
Tessaracter

Ну, я думаю, що тут також обговорювалося. Щойно зрозумів, що NextJS не встановлює жодного коду статусу. github.com/zeit/next.js/isissue/9443
Tessaracter

Видаліть заняття. Тут нічого не потрібно.
Пушп Сінгх

3

Напів офіційний приклад

Ці 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()
  }
}

Він обробляє як серверну, так і клієнтську. fetchВиклик є той , який на самому ділі отримати маркер аутентифікації, ви можете инкапсулировать це в окрему функцію.

Що я б замість цього порадив

 1. Перенаправлення на рендеринг на стороні сервера (уникайте спалаху під час SSR)

Це найпоширеніший випадок. Ви хочете переадресувати в цей момент, щоб уникнути миготіння початкової сторінки при першому завантаженні.

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. Перенаправлення на компонентDidMount (корисно, коли SSR вимкнено, наприклад, у статичному режимі)

Це резервна копія для візуалізації на стороні клієнта.

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

Я не міг уникнути прошивання початкової сторінки в статичному режимі, додавши цей пункт, тому що ви не можете перенаправляти під час статичної збірки, але це здається краще, ніж звичайні підходи. Я спробую редагувати, коли я прогресую.

Повний приклад тут

Відповідне питання, яке, на жаль, закінчується лише відповіддю клієнта


1

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

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

2
Це не повинно бути прийнятою відповіддю. Відповідно до цього github.com/zeit/next.js/isissue/4931#issuecomment-512787861 вам не слід перенаправляти getInitialProps. @Afsanefda має бути прийнятою відповіддю. А також ви використовуєте next.js, вам не потрібен маршрутизатор реагування для організації маршрутів. Далі вже обробляє це за замовчуванням.
rotimi-best

3
@ rotimi-best, наскільки я пам’ятаю, я взяв цей код із прикладу next.js. Крім того, я не використовував реактор-роутер, він був представлений як приклад того, що я хотів отримати
Артур

2
Це правильна відповідь, але лише з SSR. Він не буде перенаправлятись у статичні додатки. Редагувати: насправді це буде додано Router.push, однак клієнт Router.pushповинен замість цього перейти до методів компонентного життєвого циклу
Ерік Бурел

1

Я реалізував цю функціональність у своєму 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;
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.