Next.js Crash Course for Beginners 2021 강의노트(3): About NextJS Pages

9rganizedChaos·2021년 11월 22일
0
post-thumbnail

(🛑 해당 포스팅은 Youtube에 업로드된 Academind의 NextJS 튜토리얼 강의 콘텐츠의 강의노트입니다. 링크를 클릭하시면 강의를 들으실 수 있습니다.)

Adding Nested Pages / Paths

이전 포스팅에서 살펴보았다시피 our-domain.com/news로 라우팅을 해주기 위해서, pages 폴더에 news.js 파일을 만들어주어도 좋지만, 하나의 대안이 있다. news라는 이름의 폴더를 만들어주고 해당 폴더 안에, index.js 파일을 만들어주어도 된다!

위 두 가지 방식은 결국 같은 식으로 동작한다. 어떤 방식을 사용하든 그것은 개발자의 재량이며, 다만 개발자들은 pages 폴더 내부에 파일과 폴더를 만들면 해당 폴더명과 파일명이 path segment로 동작한다는 점을 기억하면 된다.

그렇다면, our-domain.com/news/something-important과 같이 path를 나누어주고 싶을 때는 어떻게 해야 할까? 그럴 땐 폴더 내부에 폴더를 만들어주도록 한다.

function DetailPage() {
  return <h1>The Detail Page</h1>;
}

export default DetailPage;

물론 pages 폴더 내부 폴더 내부에 또 다른 index.js를 만들어도 무방하다.

Creating Dynamic Pages

그러나 위와 같은 방식에는 결정적인 문제가 존재한다. 보통의 경우 디테일 페이지는 단 하나만 필요한 것이 아니다. 우리는 여러 아이템에 대응할 수 있는 하나의 디테일 페이지를 만들어야 한다. 유저가 디테일 페이지를 방문하면, 정적 콘텐츠를 데이터베이스로부터 페치해올 것이다. 모두 같은 페이지이지만 내부의 데이터만을 교체하는 접근방식이다. 위에서 다룬 것 something-important와 같이 하드코딩 해주는 것은 그리 현실적인 선택지가 아니다.

우리는 path에 적히는 value가 동적으로 결정되는 dynamic page를 활용해줄 것이다.

[].js

dynamic page를 위해 next.js에서 갖춰야할 특별한 문법이다. 위와 같이 작성해주면, next.js는 해당 파일을 dynamic page로 인식한다. 브라켓 사이의 식별자 이름은 임의로 지어주면 된다. 대신 파일 내부에서 해당 임의의 이름으로 해당 변수를 처리하게 된다는 점은 기억해야 한다.

아래와 같이 코드를 작성해주고나면, 마지막 path segment에 무엇을 적어주든 디테일 페이지가 렌더되는 것을 알 수 있다.

Extracting Dynamic Route Data

위에서 dynamic페이지를 어떻게 사용하는지 살펴보았다. 그렇다면 페이지가 로드되었을 때, 우리는 어떻게 url에 작성해둔 value를 끄집어낼 수 있을까. NextJS는 이를 위해 useRouter라는 훅을 제공한다.

import { useRouter } from "next/router";

위와 같이 import해주고 나면,

const router = useRouter();

페이지 내부에서 router 객체를 사용할 수 있게 된다. router 안에는 다양한 상태 데이터와 메소드들이 존재한다. (programmatic navigation 같은 것들도 가능한데 이 부분은 후에 알아보도록 한다.)

이제 url에 인코딩되어있는 value에 접근할 수 있다.

Linking Between Pages

현재는 실습을 하며 url 바에 일일이 주소를 적어주고 있지만, 사실 유저들은 그와 같은 방식으로 페이지를 이동하지 않는다. 우리는 클릭할 수 있는 요소들을 적절히 페이지에 배치해주고, 해당 요소들을 클릭했을 때 적절한 페이지로 이동시켜주어여 한다. 보통은 anchor 태그를 활용하여 이를 구현한다.

아래와 같이 코드를 작성해보면 anchor 태그를 클릭하였을때, 의도한 대로 페이지가 이동되는 것을 알 수 있다.

하지만 이는 NextJS에서 결코 바람직한 방식이 아니다.

현재는 anchor 태그를 클릭하면 refresh 아이콘이 잠시 close 아이콘으로 바뀌었다가 다시 refresh 아이콘으로 변경된다. 이건 브라우저가 새로운 요청을 보내고 새로운 html 페이지를 받아온다는 의미이다. 여기에 치명적인 단점이 존재한다. 우리의 프로젝트가 SPA가 아니라는 말이 된다. 이러한 방식이라면 새로운 html을 페치하기 위해 유저가 anchor태그를 클릭할 때마다 backend에 새로운 요청을 보낸다. 이는 결코 최선이 아니다. 게다가 a태그를 활용하는 방식은, 리액트 스테이트는 물론 redux 스토어에 보관된 것들, context states 등을 모두 잃게 된다.

우리가 노리는 최선은, initially 페이지에 진입할 때는 전부 프리렌더된 html을 받아오되, 이후 유저가 이동을 할 때는 해당 싱글페이지에 머물러 있기를 원한다. 그렇게 하면 우리는 페이지를 넘나들어도 상태 데이터를 보존하고, 유저에게 더 나은 UX를 제공할 수 있다.

NextJS가 제공하는 스페셜한 컴포넌트를 활용해야 한다.

import Link from "next/link";
import { Fragment } from "react";

function NewsPage() {
  return (
    <Fragment>
      <h1>The News Page</h1>
      <ul>
        <Link href="/news/nextjs-is-a-great-framework">
          <li>NextJS Is A Great Framework</li>
        </Link>
        <li>Something Else</li>
      </ul>
    </Fragment>
  );
}

이제는 링크를 클릭해 페이지를 이동하더라도 새로고침 아이콘에 아무런 변화가 없다. 즉, 페이지가 새로 로드되지 않는다는 의미이다. 결론은, 만일 페이지 밖으로 이동하기원한다면, a 태그를 활용하고, internal한 이동을 원한다면 Link 태그를 활용해야 한다는 것이다.

profile
부정확한 정보나 잘못된 정보는 댓글로 알려주시면 빠르게 수정토록 하겠습니다, 감사합니다!

0개의 댓글