Next.js Başka bir sayfaya / başka bir sayfaya yönlendirme


15

Ben yeniyim Next.js ve başlangıç sayfasından (yönlendirme nasıl merak ediyorum / ) için / merhaba-nextjs örneğin. Kullanıcı bir sayfa yüklediğinde ve bundan sonra path === / / hello-nextjs adresine yönlendirilip yönlendirilmeyeceğini belirleyin

In tepki-yönlendirici biz böyle bir şey yapmak:

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

1
yönlendirmenin gerçekleşmesini istediğinizde?
Nico

@ NicolòCozzani, kullanıcı bir sayfa yüklediğinde. Ve bundan sonra url === / / hello-nextjs'e yönlendirilip yönlendirilmeyeceğini belirleyin
Arthur

Yanıtlar:


23

Gelen next.jssen yönlendirebilirsiniz sayfa yüklendikten sonra kullanılarak Routerex:

import Router from 'next/router'

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

Veya Kancalı:

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

React kancaları ile nasıl yaparım ??
Tessaracter

Sınıfları kullanmadan
Tessaracter

2
@Tessaracter cevap güncellendi
Nico

2
SSR ne olacak? İlk sayfa bu yaklaşımla yanıp sönüyor
Eric Burel

@EricBurel OP açıkça "Kullanıcı bir sayfa yüklediğinde" btw bu github.com/zeit/next.js/issues/649
Nico

16

Üç yaklaşım vardır.

1.Olayları veya işlevleri yeniden inceleyin:

import Router from 'next/router';

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

2.Kancalarla yönlendirin:

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

const router = useRouter()

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

Bağlantı ile 3.Redirect:

Nextjs belgelerine dayalı olarak, <a>etiket yeni bir sekmede açmak gibi şeyler için bağlantının içinde gereklidir !

import Link from 'next/link';

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

Sunucu tarafı yönlendirmesi için başka seçenekler de vardır asPath. açıklanan tüm yaklaşımlarda, hem istemci hem de sunucu tarafını yeniden yönlendirmek için asPath ekleyebilirsiniz.


Selam! Benim
Arthur

Bu zorunlu bir yaklaşımdır. Kullanıcı işlemine yeniden yönlendirmek uygundur, ancak soruda belirtildiği gibi sayfa yüklemesindeki bir koşula dayanmaz.
Eric Burel

Ne demek istediğini anlamadım !?
Afsanefda

Soru, geçerli rota yol adına bağlı olarak otomatik olarak yeniden yönlendirmeyle ilgilidir. Yanıtlarınız geçerli ancak bu bağlamda geçerli değil: hepsi bir kullanıcı tıklaması gerektirir.
Eric Burel

@EricBurel, evet, istediğim bu değil, bu cevap sorumu çözmüyor
Arthur

3

@ Nico'nun yanıtı, sınıfları kullanırken sorunu çözer.

Eğer fonksiyonu kullanıyorsanız kullanamazsınız componentDidMount. Bunun yerine Tepki Kancalarını kullanabilirsiniz 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'da React kancaları tanıttı . sınıflardan çok daha hızlı ve verimlidir.


Bu sorun sonuç olarak ne istediğimi açıklar
Arthur

@Arthur. Oh, ama sorunuz öyle değil. @Nico ve mayın tarafından cevap tam olarak aynıdır ve bir yerini tutamaz <Switch>sen kullandığınızı React-router. <Switch>303, 302 durum kodu bile sağlamaz. Just redirects
Tessaracter

Sanırım burada da tartışıldı. NextJS'nin herhangi bir durum kodu ayarlamadığını fark ettim. github.com/zeit/next.js/issues/9443
Tessaracter

Lütfen sınıfları kaldırın. Burada bir faydası yok.
Pushp Singh

3

Yarı resmi örnek

with-cookie-authÖrnek olarak yönlendirme getInitialProps. Geçerli bir desen olup olmadığından emin değilim, ama işte kod:

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

Hem sunucu tarafını hem de istemci tarafını işler. fetchÇağrı aslında Yetkilendirme jetonu almak biri, ayrı bir işlevi içine bu enkapsüle isteyebilirsiniz olduğunu.

Bunun yerine ne öneririm

 1. Sunucu tarafı oluşturmaya yönlendirme (SSR sırasında flaştan kaçının)

Bu en yaygın durumdur. İlk yükte ilk sayfanın yanıp sönmesini önlemek için bu noktada yeniden yönlendirmek istiyorsunuz.

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'a yönlendirme (SSR devre dışı bırakıldığında faydalıdır, örneğin statik modda)

Bu istemci tarafı oluşturma için bir geri dönüş.

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

Statik modda ilk sayfayı yanıp sönmekten kaçınamadım, çünkü statik oluşturma sırasında yönlendiremezsiniz, ancak normal yaklaşımlardan daha iyi görünüyor. İlerledikçe düzenlemeye çalışacağım.

Tam örnek burada

Ne yazık ki sadece müşteri cevap ile sonuçlanan ilgili sorun


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
Bu kabul edilen cevap olmamalı. Bu github.com/zeit/next.js/issues/4931#issuecomment-512787861 uyarınca yeniden yönlendirmemelisiniz getInitialProps. @ Afefefda kabul edilen cevap olmalı. Ayrıca next.js kullanıyorsunuz, rotaları düzenlemek için tepki yönlendiricisine ihtiyacınız yok. Sonraki, varsayılan olarak bunu zaten ele alır.
rotimi-best

3
@ rotimi-best, hatırladığım kadarıyla, next.js örneğinden bu kodu aldım. Ayrıca, bir tepki yönlendirici kullanmadım, ne almak istediğime bir örnek olarak sunuldu
Arthur

2
Bu geçerli bir cevap ama yalnızca SSR ile. Statik uygulamalarda yönlendirme yapmaz. Düzenleme: aslında Router.push ekleyeceksiniz, ancak istemci tarafı Router.pushbunun yerine bileşen yaşam döngüsü yöntemlerine
gitmelidir

1

Bu işlevi, Next.JSsunucu yönünü ve istemci tarafını yönlendiren bir kök sayfa tanımlayarak uygulamamda uyguladım . Kök sayfanın kodu:

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;
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.