본문 바로가기
Frontend/Next

Next.js 설치 방법 및 기본 사용법

by Forsaken Developer 2023. 3. 9.
728x90
728x90

Next.js 설치 방법 및 기본 사용법

Next.js 설치 방법

간단히 아래의 명령어를 실행하면 설치 할 수 있다.

이 명령을 실행하려면 먼저 NodeJS가 설치되어 있어야 한다.

npx create-next-app@latest
# or
yarn create next-app
# or
pnpm create next-app

타입스크립트 기반으로 프로젝트를 설치하고 싶다면 —typescript 플래그를 추가한다.

npx create-next-app@latest --typescript
# or
yarn create next-app --typescript
# or
pnpm create next-app --typescript

먼저 pages 폴더에서 보여줄 페이지를 설정한다.

const Home = () => {
  return <h1>Home</h1>;
};

export default Home;
const Product = () => {
  return <h1>Product</h1>;
};

export default Product;

pages 폴더에 index.js 파일은 루트 페이지로 도메인에 /까지만 있는 요청이 들어오면 index.js를 읽어 들일 것이다.

pages 폴더에 product.js 라는 파일을 만든다고 하면 도메인/product 라는 요청에 해당한다.

이 페이지 파일들에 들어가야 하는 건 기본 React 컴포넌트인데해당 페이지에서 불러들여야 하는 React 컴포넌트이다.

보통 함수형 컴포넌트를 생성할 수 있고 return으로 JSX 코드를 반환한다.

참고로 위에 import React from ‘react’를 넣지 않아도 되는 NextJS 프로젝트는 이미 최신 React 설정을 지원해서 이 import를 생략해도 된다.

npm run dev로 개발 서버를 실행한다.

npm run dev

localhost:3000에 Home Page와 localhost:3000/product 에 Product Page를 볼 수 있다.

페이지 소스를 확인해보면 콘텐츠에는 내용이 없지만 읽어 들인 페이지의 소스 코드를 보면 단순히 비어 있는 뼈대만 있는 게 아니고 실제 페이지 내용이 포함되어 있다.

이 점이 기본 React 앱과 다른 중요한 차이점인데 기본 React 앱에서는 서버에서 페이지를 사전 렌더링하지 않는다.

해당 콘텐츠가 포함되어 있다는 것은 전체 페이지를 사전 렌더링했다는 뜻이다.

그래서 대기하는 동안 페이지가 깜빡거리지 않는다는 장점이 있검색 엔진도 해당 콘텐츠를 볼 수 있다.

중첩 경로

파일이나 폴더 구성과 관련해서 알아두셔야 할 다른 방법이 있다. index.js 파일은 루트 페이지, 즉 /까지만 있는 페이지를 불러온다.

index.js와 달리 따로 이름 붙인 파일을 대체하는 다른 방법이 있다.

pages 폴더 안에 product라는 새 하위 폴더를 만들고 product.js를 여기로 옮긴 후 index.js로 이름을 바꾼다.

이 특수한 index.js 파일 이름을 다시 쓰는 거예요

그래도 여전히 localhost:3000/product 로 이 페이지를 불러올 수 있다.

pages 폴더 안에 만든 폴더도 경로 세그먼트에 들어간다.

만약 여기서 product/detail 라는 경로를 설정한다고 하면 하위 폴더에 파일 하나를 더 만든다.

index.js로 루트 페이지를 만들고 detail.js 파일을 index.js와 같은 위치에 만든다.

/product/ 뒤에 아무것도 없으면 index.js 파일의 컴포넌트를 불러오고 /product/detail은 detail.js 파일의 컴포넌트를 불러온다.

물론 여기에 한 번 더 중첩 하위 폴더를 만들 수 있다.

동적페이지

같은 페이지를 반복해서 사용하여 세부 페이지에 해당 제품의 구체적인 내용을 보여줘야 할 것이다.

그래서 기술적으로는 같은 컴포넌트지만 콘텐츠는 다르다.

그래서 식별자에 이런 식으로 detail라고 파일 이름을 지정하는 것은 현실적이지 않다.

대신에 동적 페이지라는 것을 만들어야 하는데 경로에 있는 구체적인 값이 동적이다.

이렇게 /product 뒤에 product 항목을 구별할 많은 식별자가 있을 것이고 여기에 구체적인 값이 무엇이든 항상 같은 페이지를 불러와야한다.

그러려면 여기 파일 이름을 NextJS에서 사용하는 특수 구문을 적용해야하는데 대괄호를 쓰고 이 괄호 안에 식별자를 추가한다.

식별자 이름은 무엇이든 상관없지만 productId 라고 정한다면 [productId].js 이렇게 사용할 수 있다.

이 페이지를 불러올 때 URL에 입력된 구체적인 값을 추출하려면 next/router에서 useRouter 훅을 import한다.

import { useRouter } from "next/router";

const ProductDetail = () => {
  const router = useRouter();
  const productId = router.query.productId;

  console.log(productId);

  return <h1>product detail</h1>;
};

export default ProductDetail;

이 훅은 라우터 객체에 접근하고 그 라우터 객체에서 특정 데이터나 호출할 수 있는 특정 메소드를 얻을 수 있다.

여기서 URL에 인코딩된 값, 즉 이 동적 경로 세그먼트의 구체적인 값에 접근할 수 있다.

이 라우터 객체에서 query 속성을 사용하면 중첩 객체에 접근할 수 있다.

이 query 객체에서 대괄호 안에 썼던 식별자를 속성 이름으로 넣으면 된다.

이렇게 URL에 인코딩된 구체적인 값을 얻을 수 있는데 제품을 가져올 수 있는 데이터베이스나 백엔드 API가 있다면 백엔드 API에 요청을 보내서 productId에 해당하는 제품 항목을 가져올 수 있다.

Link

웹사이트에 링크가 있고 사용자들은 링크를 이용해서 탐색한다.

링크를 만들려면 앵커 태그를 이용하여 연결하고자 하는 URL을 인코딩할 수 있다.

const Product = () => {
  return (
    <>
      <h1>Product</h1>
      <ul>
        <li>
          <a href="/product/productDetail">Product detail</a>
        </li>
      </ul>
    </>
  );
};

export default Product;

클릭하면 이 특정 값을 통해 세부 페이지로 들어올 수 있고 제대로 작동하지만 이건 NextJS 앱에서 탐색하는 차선책일 뿐이다.

작동은 하지만 제가 링크를 클릭할 때 새로고침 아이콘이 잠깐 X 표시가 떴다가 새로 고침 아이콘으로 돌아온다.

이는 항상 브라우저가 새 요청을 보내고 새 HTML 페이지를 받는다는 신호이다.

사용자가 탐색할 때마다 새 요청을 백엔드에 보내고 새로운 HTML 페이지를 받기 때문에 싱글페이지 어플리케이션이 아니다.

이러면 리덕스 상태나 컨텍스트 상태 등 저장했던 상태들이 없어질 수 있다.

싱글 페이지 애플리케이션으로 유지하려면 링크를 다르게 만들어야 한다.

next/link에서 제공하는 Link를 import 하여 앵커 태그 대신에 사용하면 된다.

href 프로퍼티는 그대로 두고 링크의 목적지를 설정한다.

import Link from "next/link";

const Product = () => {
  return (
    <>
      <h1>Product</h1>
      <ul>
        <li>
          <Link href="/product/productDetail">Product detail</Link>
        </li>
      </ul>
    </>
  );
};

export default Product;

이 특수 컴포넌트 Link가 앵커 태그를 렌더링하고 이 앵커 태그에 클릭을 감지해서 클릭을 하면 브라우저가 기본 동작으로 새 HTML 페이지를 받는 요청을 보내지 못하도록 하고 대신에 불러올 컴포넌트를 읽어 들이고 URL을 변경하여 페이지가 바뀐 것처럼 보이게 한다.


Component와 pageProps

페이지가 있을 때 이 공통 레이아웃을 모든 페이지 콘텐츠에 적용한다고 생각하면 페이지 컴포넌트에 하나하나 들어가서 레이아웃에 콘텐츠를 집어넣어야 할 것이다.

이럴 때 _app.js 파일이 아주 유용하다.

여기 MyApp 컴포넌트가 정의되어 있는데 이 특수 컴포넌트는 NextJS가 렌더링하는 최상위 컴포넌트처럼 작동한다.

여기서 프로퍼티를 받고 구조 분해 할당을 해서 꺼내는 정보는 Component와 pageProps이다.

Component는 렌더링 될 실제 페이지 콘텐츠를 저장하고 있는 프로퍼티이고 페이지를 전환할 때마다 변한다.

pageProps는 페이지가 받는 특수 프로퍼티이다.

그렇다면 _app.js를 이용해서 이 컴포넌트를 Layout이나 원하는 컴포넌트 안에 넣으면 공통 레이아웃을 공유할 수 있다.

import "../styles/globals.css";
import Layout from "../components/layout/Layout";

function MyApp({ Component, pageProps }) {
  return (
    <Layout>
      <Component {...pageProps} />
    </Layout>
  );
}

export default MyApp;
728x90
반응형

'Frontend > Next' 카테고리의 다른 글

Next.js 사용하는 이유  (0) 2023.03.03

댓글