프로그래밍/Next

[Next] Framework / Pages / Pre-Rendering / Routing

라다디 2022. 7. 8. 01:46

1. Creating a Project

NextJS 프로젝트 최신 버전으로 생성

→ npx create-next-app@latest 

 

타입스크립트 사용

→ npx create-next-app@latest --typescript

 

실행

→ npm run dev

 

2. Library vs Framework 

라이브러리는 개발자가 사용하고 싶을 때 불러와서 원하는 대로 코드를 작성하는 것이 가능하다. 

리액트는 개발자가 원할 때 부르고 원할 때 사용하는 라이브러리이다.

 

프레임워크에서는 특정한 규칙을 따라서 특정한 걸 해야한다.

규칙을 따랐을 때 모든 게 정상적으로 잘 동작하고 프레임워크도 개발자를 도울 수 있다. 

개발자가 규칙을 따라서 코드를 적절한 위치에 잘 작성하면 프레임워크가 그 코드를 호출하여 모든 걸 동작시킨다.

넥스트는 자동적으로 우리가 pages 안에 about이라는 페이지를 만들면 /about에 갔을 때 그 컴포넌트를 보여준다.

 

라이브러리

개발자가 어떤 프로그램을 가져다 쓰는것 (React: 렌더링할때 ReactDOM.render()를 불러와서 사용)

사용자가 파일 이름이나 구조 등을 정하고, 모든 결정을 내림

 

프레임워크

개발자의 코드를 프로그램이 불러오는 것 (NextJS: 정해진 규칙에 따라 코드를 작성하면 렌더링)

파일 이름이나 구조 등을 정해진 규칙에 따라 만들고 따름

 

라이브러리와 프레임워크의 주요 차이점 - Inversion of Control (통제의 역전)
라이브러리에서 메서드를 호출하면 사용자가 제어할 수 있다.
그러나 프레임워크에서는 제어가 역전되어 프레임워크가 사용자를 호출한다.

3. Pages 

NextJS 프로젝트에서 page를 추가하기 위해서는 리액트 컴포넌트를 export하고 있는 파일을 pages 폴더 안에 두면 된다. 

그러면 NextJS가 파일의 이름을 가져다가 URL의 이름으로 쓴다.

 

pages/about.js (pages 폴더 안에 있는 파일명에 따라 route가 결정)
→ localhost:3000/about (O)
→ localhost:3000/about-us(X)

 

create react-app만을 한다면, React Router DOM을 다운받고, 설정하고, router를 만들고, routes를 설계하고, component를 import하고 router를 render해야 하지만 NextJS로 일을 하게 되면 이 모든 것들이 다 되어 있는 것이다. 

 

파일명이 그대로 URL로 들어가기 때문에 파일의 이름이 중요하다. 

반면에 컴포넌트의 이름은 그닥 중요하지 않다. 중요한 것은 컴포넌트가 export default여야 한다는 것이다. 

만약 default로 export하지 않는다면 사이트에서 /about에 들어갔을 때 default export가 react component가 아니라고 에러가 발생한다. 

 

중요한 것은 함수가 default로 export되는 것과 파일명이다.

없는 파일명으로 URL을 입력하면 404페이지가 뜬다. (create react-app을 사용했다면 404페이지도 직접 만들어야 함)

 

pages 폴더 안에 넣을 수 있는 몇 가지 예외사항

1. index.js의 경우에는 앱이 시작하는 파일이다. index.js는 앱의 홈페이지로 연결 시켜준다. 홈페이지는 그냥 슬래시로만 표시한다. (/index(X))

2. jsx를 쓰고 있다면 import react from "react"를 쓸 필요가 없다. 다만 useState,useEffect, lifecycle method 같은 애들을 써야 할 경우에는 import를 해야 한다.

 

4. Static Pre Rendering

NextJS의 가장 좋은 기능 중 하나는 앱에 있는 페이지들이 미리 렌더링 된다는 것이다. 

이것들은 정적(static)으로 생성된다. 

 

create react app과 NextJS의 차이점은 create react app은 client-side render를 하는 앱을 만든다는 것이다. 

client-side rendering의 뜻은 브라우저가 UI를 만드는 모든 작업을 한다는 것을 의미한다. 

 

React로 렌더링된 것들은 유저가 보는 HTML 소스코드 안에 들어있지 않다.

브라우저는 HTML을 가져올 때 비어있는 div로 가져온다.

브라우저가 자바스크립트 코드를 요청해서 자바스크립트와 리액트를 실행시키고, 리액트가 렌더링한 후에 유저는 UI를 볼 수 있다.

 

CSR의 경우 아주 느린 네트워크 환경에서 새로고침을 하면 처음에 하얀 화면이 나온다.

브라우저는 자바스크립트 코드가 왔을 때만 UI를 만들 수 있으므로 이 순간에 자바스크립트 코드를 요청하고 있는 것이다. 

이게 바로 브라우저가 자바스크립트, 리액트 등 모든 것을 fetch한 후에야 UI가 보이는 client-side rendering이다.

 

NextJS 웹사이트의 소스코드를 보면 실제 HTML이 있다.

유저가 매우 느린 연결을 하고 있거나 자바스크립트가 비활성화 되어 있어도 유저는 HTML을 볼 수 있다.

api로부터 가져오는 데이터가 로딩되는 데에 오랜 시간이 걸릴 수 있지만 적어도 어떠한 HTML은 볼 수 있는 것이다.

NextJS컴포넌트의 초기 상태로 pre-rendering을 한다.

 

리액트를 프론트엔드 안에서 실행하는 것을 hydration이라고 부른다.

왜냐하면 NextJS는 리액트를 백엔드에서 동작시켜서 초기 상태의 컴포넌트들을 render한다.

렌더링이 끝났을 때 그건 HTML이 되고 유저는 자바스크립트와 리액트가 로딩되지 않았더라도 콘텐츠를 볼 수 있게 된다.

로딩이 끝나면 기본적으로 이미 존재하는 것들과 연결이 되어서 일반적인 리액트 앱이 되는 것이다.

 

이렇게 되면 두 방면에서 장점이 있다.

1. 유저가 코드를 다운받아 리액트를 실행시키길 기다리지 않아도 된다.

2. SEO(검색 엔진 최적화)에 좋다. 

 

5. Routing

NextJS 어플리케이션에서 a 태그를 네비게이팅하는 데에 사용하면 안된다.

a 태그를 이용하면 브라우저가 다른 페이지로 보내기 위해 전체 페이지를 새로고침하는데 그러면 속도가 느려진다. 

 

NextJS에는 앱 내에서 페이지를 네비게이트할 때 사용해야만 하는 특정 Link 컴포넌트가 존재한다.

Link는 NextJS 어플리케이션의 클라이언트 사이드 네비게이션을 제공해준다.

import Link from "next/link";
...
      <Link href="/">
        <a>Home</a>
      </Link>

웹사이트를 새로고침할 필요가 없기 때문에 속도가 빠르다. 

Link는 단지 href만을 위한 것이기 때문에 스타일링을 하고 싶거나 className을 달고 싶다면 a 태그에 하면 된다.

 

앱의 함수 컴포넌트에서 router객체 내부에 접근하려면 userRouter() 훅을 사용한다.

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 === "/about" ? "red" : "blue" }}>
          About
        </a>
      </Link>
    </nav>
  );
}

router를 콘솔에 찍어보면 location에 관한 정보를 얻을 수 있다. 

내가 어디 페이지에 있는지 알고 싶다고 하면 router.pathname을 이용하면 된다. 

 

Router를 설치하거나 렌더링하지도 않았지만 NextJS로부터 제공되었으므로 잘 작동한다.

 


📌 아래 강의의 내용을 정리한 글입니다.