Next.js를 다른 페이지로 /에서 다른 페이지로 리디렉션


15

Next.js의 새로운 기능으로 시작 페이지 ( / )에서 / hello-nextjs 로 리디렉션하는 방법이 궁금합니다 . 사용자가 페이지를로드 한 후 path === / / 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로 경로 재 지정
Arthur

답변:


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 hooks로 어떻게합니까 ??
Tessaracter

수업을 사용하지 않고
Tessaracter

2
@Tessaracter 답변이 업데이트 됨
Nico

2
SSR은 어떻습니까? 초기 페이지는이 방법으로 깜박이는
에릭 Burel

@EricBurel OP는 명확하게 "한 번 사용자가 페이지를로드하면"btw이 github.com/zeit/next.js/issues/649를
Nico

16

세 가지 접근 방식이 있습니다.

1. 이벤트 또는 기능에 대한 리디렉션 :

import Router from 'next/router';

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

후크로 2.Redirect :

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를 추가하여 클라이언트와 서버 측을 모두 리디렉션 할 수 있습니다.


안녕! 내 솔루션을 볼 수 있습니다
Arthur

이것은 명령 방식입니다. 질문에 명시된 바와 같이 사용자 작업을 리디렉션해도 괜찮지 만 페이지로드 상태를 기반으로하지는 않습니다.
Eric Burel

무슨 뜻인지 모르겠어!?
Afsanefda

현재 경로 경로 이름에 따라 자동으로 리디렉션하는 문제가 있습니다. 귀하의 답변은 유효하지만이 상황에서는 적용 할 수 없습니다. 모두 사용자 클릭이 필요합니다.
Eric Burel

@EricBurel, 예, 이것은 내가 원하는 것이 아닙니다.이 답변은 내 질문을 해결하지 못합니다
Arthur

3

@Nico의 답변은 수업을 사용할 때 문제를 해결합니다.

기능을 사용하면 사용할 수 없습니다 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

@Arthur. 아, 그러나 당신의 질문은 그렇게 말하지 않습니다. @Nico와 내 대답은 정확히 동일하며 <Switch>에서 사용 하는 것을 대신합니다 React-router. 심지어 <Switch>어떤 303, 302 상태 코드를 제공하지 않습니다. 리디렉션 만
Tessaracter

글쎄, 나는 여기서도 논의했다고 생각한다. NextJS가 상태 코드를 설정하지 않았다는 것을 깨달았습니다. github.com/zeit/next.js/issues/9443
Tessaracter

수업을 삭제하세요. 여기서는 아무 소용이 없습니다.
Pushp Singh

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. componentDidMount에서 리디렉션 (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/issues/4931#issuecomment-512787861 에 따르면 리디렉션해서는 안됩니다 getInitialProps. @Afsanefda가 허용되는 답변이어야합니다. 또한 next.js를 사용하므로 경로를 구성하기 위해 라우터를 반응 할 필요가 없습니다. 다음은 이미 기본적으로 처리합니다.
rotimi-best

3
@ rotimi-best, 내가 기억하는 한이 코드는 next.js 예제에서 가져 왔습니다. 또한, 나는 반응 라우터를 사용하지 않았다, 그것은 내가 얻고 싶은 것의 예로서 제시되었다
Arthur

2
이것은 정답이지만 SSR에만 해당됩니다. 정적 앱에서는 리디렉션되지 않습니다. 편집 : 실제로 당신은 그러나 클라이언트 측, Router.push 추가됩니다 Router.push대신 구성 요소 라이프 사이클 방법에 가야한다
에릭 Burel

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;
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.