Next.js (2) - Page Router

김태완·2024년 12월 9일
post-thumbnail

Page Router

Page Router 란❓

  • Pages 폴더의 구조를 기반으로 페이지 라우팅을 제공하는 기능🌟
  • React Router 처럼 특정 조건을 기준으로 웹 서비스 내 페이지를 분할하고, 분할된 페이지 간의 이동을 처리하는 기능
  • pages 라는 폴더의 구조를 기반으로 페이지를 라우팅한다.
  • 해당 경로안에 폴더와 파일을 두게 되면 자동으로 이 폴더와 파일들의 경로와 이름에 따라서 페이지 라우팅이 제공된다.
  • 아래와 같이 동적 경로(Dynamic Routes)를 갖는 페이지의 라우팅도 설정 가능하다.
    • 이때 파일명을 대괄호로 묶어주면 가변적인 값을 매핑할 수 있다.

Query String 사용하기

  • 경로의 끝에 물음표와 함께 명시되는 값이다. 페이지 경로에 영향을 주지 않는다.
  • 컴포넌트에서 이 값을 사용하려면 useRouter 라는 훅을 next/router로 부터 불러와야한다.
    • next/navigation 패키지는 App Router에서 사용되는 패키지이다!😐
    • 이렇게 하면 router 객체 안에 쿼리 스트링이 잘 찍혀있다.
  • 그런데 객체가 콘솔에 두 번 출력된다❓
    • 넥스트 앱이 우리가 전달한 이 쿼리 스트링을 읽는 과정중에 컴포넌트를 한 번 더 렌더링하기 때문이다.
    • 그래서 첫 객체 출력문에는 쿼리 스트링을 읽어오지 못해서 빈 칸이다.

URL Parameter 사용하기

  • 대괄호를 사용해서 파일을 생성해준다.
  • 그러면 넥스트가 대괄호가 포함된 파일명을 보고 가변적인 값 즉 URL Parameter를 갖는 동적 경로에 대응하는 파일이다는 것을 인식한다.
  • 그래서 값이 뭐가 되던 파일에 작성된 컴포넌트를 페이지로써 화면에 렌더링 시키도록 설정한다.
    • 여기서 전달된 파라미터 값을 컴포넌트에서 꺼내서 쓰고 싶다면?
    • 쿼리 스트링처럼 useRouter 훅을 사용하면 된다. 똑같은 방식으로 router 객체에 저장된다.
  • 만약 파라미터가 여러개라면??
    • [...id].tsx 처럼 Catch All Segement를 사용한다.
    • 이는 여러개의 id가 연달아 들어올 수 있고 그러한 모든 id에 대응하겠다는 뜻이다.
    • segment는 구간인데 / 로 구분되는 모든 구간에 대응하는 페이지를 만들겠다는 것이다.
    • 이때 전달된 파라미터들을 출력해보면 배열 형태로 전달된다는 것을 확인할 수 있다.
  • HTML에서 하던 것처럼 a 태그를 사용한다면 CSR 방식으로 페이지를 이동시키는게 아닌 일반적인 방식으로(서버에게 매번 페이지를 요청하는 방식) 페이지를 이동시킨다.
  • 그래서 넥스트 자체 내장 컴포넌트인 Link 컴포넌트를 이용하는 것이 좋다.
  • 사용방법은 a태그와 동일하게 href로 경로를 설정해준다.
Programmatic Navigation
  • 특정 버튼이 클릭 되었거나 아니면 특정 조건이 만족했을 경우에 어떤 함수 내부에서 페이지를 이동시키는 방법을 말한다.
  • useRouter 훅을 사용하는데, router 객체의 push 매서드를 사용한다.
    • 이때 push 매서드는 인수로 전달받은 경로로 페이지를 클라이언트 사이드 렌더링 방식으로 이동시켜준다.
  • 참고로 push 매서드 말고도 다양한 매서드가 있다.
    • replace: 뒤로 가기를 방지하면서 페이지를 이동시키는 매서드
    • back: 페이지를 뒤로 이동시키는 매서드

프리패칭(Pre-Fetching)

  • 페이지를 '사전에 미리 불러온다' 라는 뜻을 가지고 있다.
  • 즉, 현재 사용자가 보고 있는 페이지 내에서 이동할 가능성이 있는 모든 페이지들을 사전에 미리 불러놓는 기능이다.
  • 이를 통해 페이지 이동을 매우 빠른 속도로 지체 없이 처리해주기 위함이다.
❓이미 사전 렌더링을 통해 페이지가 렌더링 됐는데, 왜 프리패칭을 해야해?
  • 넥스트는 JS 파일(리액트 컴포넌트)들을 자동으로 페이지별로 스플리팅 즉, 페이지별로 분리해서 저장해둔다.
  • 그래서 최초에 JS 번들을 전달할때 현재 페이지에 필요한 JS Bundle만 전달된다는 것이다.🌟
    • 이를 통해서 JS 번들의 양을 줄일 수 있다는 장점이 있다. 용량이 너무 커지게 되면 다운로드 속도도 느려지고, Hydration 시간도 오래 걸리게되니 TTI가 늦어지게 된다.
❓그러면 페이지 이동시 CSR방식을 사용하지 않은 것 아니야?
  • 필요한 페이지의 JS 코드를 계속 요청해서 받아와야 하잖아...?
  • 그래서 Pre-Fetching 기능을 사용한다.
  • 원래라면 위 사진처럼 매번 요청을 했어야 했지만!
  • 프리패칭을 통해 페이지 이동 요청이 발생하기 전에 미리 불러와 놓음으로 페이지 이동을 빠르게 동작할 수 있도록 한다.
  • 그래서 사실은 초기 접속 요청시 받아오는 JS 번들은 아래와 같이 모든 JS번들을 불러오는 것이 아니다.

    결론은 이를 통해 초기 접속 요청 시에 Hydratin을 더 빠르게 처리할 수 있도록 만들어주면서도 동시에 프리패칭을 통해 초기 요청 이후에 페이지 이동까지 빠르게 이동할 수 있도록 한다!

  • 그런데 이 프리패칭은 개발모드에서는 실행이 되지 않아요. 빌드를 해야한다. 그리고 프로덕션 모드로 실행해서 확인이 가능하다.
    • 그래서 위 상태에서는 다른 페이지로 이동해도 별도의 네트워크 요청이 이루어지지 않는다. 다만 캐시가 만료된 상태라면 요청을 할 수 있다.
    • Link 태그로 이루어진 페이지만 프리패칭을 하는데, 만약 프로그래매틱하게 경로를 만들어줬다면, router의 prefetch 라는 메서드를 사용하면 명시적으로 프리패칭을 사용할 수도 있다.
  • 프리패칭이 필요 없어졌다면?
    • prefetch 옵션을 false로 주면 된다.

API Routes

Next.js에서 API를 구축할 수 있게 해주는 기능
  • Pages 폴더 내부 api 폴더 안에 파일을 만들어주면 해당하는 파일은 웹페이지가 아닌 API Routes로서 즉, API 응답을 정의하는 파일로서 자동으로 설정된다.
  • API 경로는 디렉토리 구조와 동일하다.
  • 그래서 API 경로로 요청을 보내게되면 해당 파일 내부 함수를 실행한다.
  • 그러나 특별한 경우가 아니라면 잘 사용하지 않는 기능이다.

이미지 출처: 한입 넥스트

profile
중고

0개의 댓글