React

[NextJS] Route, Routing, Dynamic Routes 사용 방법

cob 2022. 10. 13. 10:03

 

* NextJS 프로젝트 설치 및 실행 *
https://cocococo.tistory.com/42

* Source Code *
https://github.com/kangilbin/React.js/tree/master/nextjs-study

 

 


1. Routes

pages 폴더 안에 새로운 page 파일을 넣게 되면 자동으로 이동할 수 있다.

page 추가

( about.tsx )

export default function Potato() {
  return "about";
}
  • export default로 만들어 주어야한다.
  • 함수명은 상관없다.

page url

  • 파일 이름이 그대로 url로 들어간다.
  • index 파일은 메인 홈페이와 연결되어있다. http://localhost:3000  => index 페이지

 

 


2. Routing

import Link from "next/link";

export default function NavBar() {
	return (
		<nav>
			<Link href="/"><a className="hello" style={{color:black}}>Home</a></Link>
			<Link href="/about"><a>About</a></Link>
		</nav>
	);
};
  • 따로 Router 라이브러리를 설치하지 않아도 작동한다.
  • Routing 하는데 <a /> 태그를 사용할 수 없고, Link태그를 사용해야 한다.
// <a />태그만 단독 사용 x
<a href='URL'>About</a>

// Link 내부에 <a /> 
<Link href="/about"><a>About</a></Link>
  • 새로고침 할 경우 페이지 전체를 렌더링 하지 않기 위해 NextJS에서 라우팅 시에 사용해야 하는 방법이(Link 컴포넌트) 존재한다.

 

 

2-1) Props 전달

import Link from "next/link";

export default function NavBar() {
	return (
		<nav>
			<Link href="/"><a className="hello" style={{color:black}}>Home</a></Link>
		</nav>
	);
};
  • Prop을 주기 위해서 <Link /> 안에 <a />를 사용하여 <a /> 태그에 Prop 값을 전달해 준다.

 

 

2-2) useRouter Hook ( URL 정보)

useRouter Hook은 location에 관한 정보를 가지고 있다. asPath, back, basePath 등
import Link from "next/link";
import { useRouter } from "next/router";

export default function NavBar() {
	const router = useRouter();
	return (
		<nav>
			<Link href="/">
				<a style={{color: router.pathname === "/" ? "red" : "blue"}}>Home</a>
			</Link>
			<Link href="/about">
				<a style={{color: router.pathname === "/abount" ? "red" : "blue"}}>About</a>
			</Link>
		</nav>
	);
};
  • pathname에 페이지 url를 가지고 있다.

 

 

 


3. Dynamic Routes (동적 라우트)

page 추가

  • 패키지 경로url 경로와 맵핑해 준다.
* http://{URL} / {패키지 경로}  *
http://localhost:3000/movies/all

 

3-1) 서브 경로의 index 페이지 설정

패키지 index 페이지

  • /moves 주소와 하위 주소까지 가지고 싶다면 moves 폴더 안에 index 이름으로 파일을 만든다.
    ( http://localhost:3000/movies => index 페이지)

 

 

3-2) 변수를 포함하는 Dynamic URL 

Dynamic URL

  • 파일명을 대괄호([]) 만들면 Dynamic URL이라고 알려준다.
  • 파일명([id])과 전달받은 파라미터 변수명이 같아야 한다.
* http://{url}/movies/:id *
ex) http://localhost:3000/movies/539681

 

(URL 객체로 페이지 이동)

import { useRouter } from 'next/router'

export default function ReadMore({ post }) {
  const router = useRouter()

  return (
    <button
      type="button"
      onClick={() => {
        router.push({
          pathname: '/movies/[id]',
          query: { id: post.id },
        })
      }}
    >
      Click here to read more
    </button>
  )
}

 

( [id].tsx )

import { useRouter } from "next/router";

export default function Detail(){
	const route = useRouter();
	console.log(route)
	return "detail";
}
  • 함수명은 상관없다.

Route Obejct

  • 파라미터는 route Object의 query안에 있다. key값은 대괄호 안에 있는 파일명이랑 동일하다.

 

 

3-3) Navigating 방법 예

import Seo from "./../components/Seo";
import Link from "next/link";
import { useRouter } from "next/router";

interface IMoviProp {
  id: number;
  original_title: string;
  poster_path: string;
}

export default function Home({ results }: { results: IMoviProp[] }) {
  const router = useRouter();
  const onClick = (id: number) => {
    router.push(`/movies/${id}`);
  };
  return (
    <div>
      <Seo title="Home" />
      {results?.map((movie) => (
        <div onClick={() => onClick(movie.id)} className="movie" key={movie.id}>
          <img src={`https://image.tmdb.org/t/p/w500${movie.poster_path}`} />
          <h4>
            <Link href={`/movies/${movie.id}`}>
              <a>{movie.original_title} </a>
            </Link>
          </h4>
        </div>
      ))}
		</div>
  );
}

 

( 마스킹 처리(as) url로 state 넘겨주는 방법 )

<Link 
	href={{
		 pathname: `/movies/${movie.id}`,
	   query: {
	      id,
	      title: "potatos",
	    },
		}}
		as={`/movies/${movie.id}`}
	>
	<a>{movie.original_title} </a>
</Link>

 

( 이벤트를 사용한 url로 state 넘겨주는 방법 )

const router = useRouter();
const onClick = (id: number) => {
    router.push({
      pathname: `/movies/${id}`,
      query: {
        id,
        title: "potatos",
      },
    });
  };

event로 parameter 넘겨주기

(이벤트를 사용한 url 마스킹 처리 방법 )

const onClick = (id: number) => {
    router.push(
      {
        pathname: `/movies/${id}`,
        query: {
          title: "potatos",
        },
      },
      // 마스킹하고 싶은 url 입력
      `/movies/${id}`
    );
  };

 

 

3-4) catch-all URL

뭐든 무한대로 잡아내는 url이다.

catch all
url 경로

  • […id] : 파일명(파일명은 상관없음) 앞에 … 을 주게 되면 모든 주소에 접근할 수 있다.

catch all param

  • query값이 배열로 변경된다.

 

( [...params].tsx param 가져오기 )

import { NextRouter, useRouter } from "next/router";

// Obejct가 아니기 때문에 type으로 선언문으로 배열값의 type을 지정해준다.
type routerParam = [string, string];

export default function Detail() {
  const router: NextRouter = useRouter();
  // 최초 렌더링시 HTML 파일만 내려오기 때문에 useRouter 값을 제대로 불러오지 못한다 그렇기 때문에 초기에 빈배열 추가해준다.
  const [title, id] = (router.query.params || []) as routerParam;
  return (
    <div>
      <h4>{title}</h4>
    </div>
  );
}
  • 초기값 빈 배열을 설정해 주어야 한다.

 

 

3-5) SSR (Server Side Rendering)로 백엔드에서 받아온 param 정보를 넘겨주는 방법.

* 공식 문서 *
https://nextjs.org/docs/api-reference/data-fetching/get-server-side-props#getserversideprops-with-typescript
import { GetServerSideProps, InferGetServerSidePropsType } from "next";
import { NextRouter, useRouter } from "next/router";
import { ParsedUrlQuery } from "querystring";


type routerParam = [string, string];

export default function Detail({
  params,
}: InferGetServerSidePropsType<typeof getServerSideProps>) {
  const [title, id] = (params || []) as routerParam;
  return (
    <div>
      <h4>{title}</h4>
    </div>
  );
}

interface IServerParams extends ParsedUrlQuery {
  params: string;
}
export const getServerSideProps: GetServerSideProps = async (context) => {
  const params = context.params as IServerParams;

  return {
    props: params,
  };
};
  • API 요청이 아닌 단순 페이지 이동이기 때문에 느려질 가능성은 거의 없다.
반응형