게으른개발너D

Framework Overview 2 - Static Pre Rendering and Routing 본문

개발/NextJS

Framework Overview 2 - Static Pre Rendering and Routing

lazyhysong 2023. 11. 23. 18:34

1. Static Pre Rendering

next.js의 가장 좋은 기능 중 하나는, 앱에 있는 페이지들이 미리 렌더링 (Pre-Rendering)된다는 점이다.

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

 

1.1 create-react-app과 next.js의 차이점

create-react-app

create-react-app은 client-side render를 하는 앱을 만든다.

client-side render는 우리 브라우저가 유저가 보는 UI를 만드는 모든 것을 한다는 것을 의미한다.

예를들어 create-react-app으로 만든 우리 프로젝트를 살펴보면 header, menu, card 등 다양한 것들이 많은데, 걔네들은 유저가 보는 HTML 소스코드 안에 들어있지 않다. 소스 코드를 살펴보면 아래처럼 div 하나만 나와있을 것이다.

<div id="root"></div>

 

브라우저가 react.js를 다운받고 우리 코드를 다운 받았을 때, 그때 react.js는 다른 모든 것들을 렌더링하고 유저는 header나 menu같은 것들을 보게되는 것이다.

브라우저가 JS를 요청하고 client-side의 JS가 모든 UI를 만들게 된다.

 

만약 브라우저가 느리다면 브라우저가 JS파일을 요청하고 다운받기 전 화면이 나오므로 하얀화면이 나오게 될 것이다.

자바스트립트가 disabled 될때도 마찬가지이다.

 

next.js

next.js는 pre-render를 한다.

javascript를 비활성화하고 next.js로 만든 프로젝트 페이지를 새로고침 시켜보자.

next.js의 소스코드를 보면 소스코드 어딘가에 우리가 구현한 HTML이 있는걸 볼 수 있다.

유저의 브라우저가 매우 느린 연결을 하고 있거나 JS가 완전히 비활성화 되어있어도 유저는 HTML을 볼 수 있다.

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

 

우리가 js로 어떤 active를 하여 화면의 요소가 변경 된 후 소스코드를 보면 변경된 요소 대신 초기상태의 요소가 적용되어있다.

이렇게 next.js는 초기 상태로 pre-rendering을 한다. 그리고나서 react.js가 (클라이언트로) 전송되었을 때 react.js 앱이 된다.

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

왜냐면 next.js는 react.js를 백엔드에서 동작시켜서 페이지를 미리 만드는데, 렌더링이 끝났을 때 코드는 HTML이 되고 next.js는 그 HTML을 페이지의 소스코드에 넣어준다.

그럼 유저는 js와 react.js가 로딩되지 않더라도 콘텐츠를 볼 수 있게 된다.

 

pre-rendering이 짱인 점은 SEO에 좋다는 점이다. 유저들이 우리 웹사이트에 오면 이미 무언가가 있기 때문이다.

 

 

 

 

 

2. Routing

2.1 link의 잘못된 예

네비게이션 컴포넌트를 만들어보자.

components 폴더 안에 NavBar.js 파일을 만들자.

// NavBar.js

function NavBar() {
  return <nav>
    <a href="/">Home</a>
    <a href="/about">About</a>
  </nav>
}

export default NavBar;

그리고 index.js와 about.js에 위의 컴포넌트를 추가해 준다.

 

// index.js

import NavBar from "../components/NavBar";

function Home() {
  return <div>
    <NavBar />
    <div>Hello</div>
  </div>
}

export default Home;

 

이제 navbar에 있는 링크를 클릭해 주면 해당 링크가 가리키는 페이지로 이동하게 된다.

 

그런데 NavBar 컴포넌트를 보면 a 코드쪽에 ESLint 에러가 발생하고 있다.

메세지를 보면 a 태그를 Home페이지로 이동하는데 사용하지마라고 적혀있다.

 

next.js 어플리케이션에서 anchor 태그를 네비게이팅하는 데에 사용하면 안되는 이유는 next.js에 앱 내에서 페이지를 네비게이트할 때 사용해야만 하는 특정 컴포넌트가 존재하기 때문이다.

react.js에서 React Router Link를 사용해야만 할 때와 이유가 같다.

만약 a태그로 페이지 이동을 한다면 페이지가 리로드되게 된다. 이 뜻은 브라우저가 다른 페이지로 보내기 위해 전체 페이지를 새로고침한다는 뜻이다.

 

2.2 Link component

위의 메세지를 읽어보면 next/link로부터 임포트되는 Link 컴포넌트를 사용하라고 되어있다.

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

NavBar.js를 아래와 같이 수정해주자.

// NavBar.js

import Link from 'next/link';

function NavBar() {
  return <nav>
    <Link href="/"><a>Home</a></Link>
    <Link href="/about"><a>About</a></Link>
  </nav>
}

export default NavBar;

a 태그를 Link로 감싸주고 href attribute는 Link 컴포넌트 안에 넣어준다.

 

이제 화면에서 navbar의 링크를 클릭하면 리로딩되는 것 없이 화면이 빨리빨리 전환된다.

Link 안에 a 태그를 넣는 것처럼 react router dom에서 처럼 Link 안에 바로 Home 글자를 넣을 수도 있다.

하지만 next/link에서 제공하는 Link 컴포넌트에 style이나 className같은 것을 적용시킬 수 없다.

Link는 오직 href를 위한 것이다.

 

 

cf)

https://nextjs.org/docs/messages/invalid-new-link-with-extra-anchor

 

Invalid `<Link>` with `<a>` child

Using App Router Features available in /app

nextjs.org

next.js 13버전부터는 Link 안에 a 태그를 넣으면 에러가 나도록 되어있다.

$npx @next/codemod new-link .

새로운 Link 컴포넌트를 사용할 수 있도록 위의 명령어를 입력하여 업데이트 시켜주자.

 

// <Link href="/">
//   <a id="hi">Hi</a>
// </Link>

<Link href="/" id="hi">Hi</Link>

그럼 위의 주석처리된 코드를 아래처럼 사용할 수 있다.

 

 

 

 

2.3 router

이제 어떠한 hook을 사용하여 라우터와 연결해보자.

바로 next.js에 있는 useRouter 훅을 사용할 것이다.

// NavBar.js

import Link from 'next/link';
import { useRouter } from 'next/router';

function NavBar() {
  const router = useRouter();
  return <nav>
    <Link href="/"><a>Home</a></Link>
    <Link href="/about"><a>About</a></Link>
  </nav>
}

export default NavBar;

 

보다시피 모든 게 이미 install되어 있으니 그냥 갖다 쓰기만 하면 된다.

 

package.json을 보면 dependencies도 매우 적다.

갖고 있는 전부가 next와 react, react-dom이다.

react-router-dom을 install할 필요도 없다 그 외 웬만한건 뭐든 install할 필요가 없다.

 

위 코드에서 선언한 router를 console.log로 찍어보자.

 

asPath, back, basePath, pathname같은  우리 location에 관한 정보들을 얻을 수 있다.

 

해당 정보들을 이용하여 우리가 현재 home에 있는지 about에 있는지 알아보자.

a 태그에 style을 추가하자.

// NavBar.js

import Link from 'next/link';
import { useRouter } from 'next/router';

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>
}

export default NavBar;

index 페이지에 접속하면 Home 링크가 빨간색으로 변하고 about 페이지에 접속하면 About 링크가 빨간색으로 변하게 된다.

 

 

 


출처

노마드코더

https://nomadcoders.co/nextjs-fundamentals/lobby?utm_source=free_course&utm_campaign=nextjs-fundamentals&utm_medium=site

 

NextJS 시작하기 – 노마드 코더 Nomad Coders

NextJS for Beginners

nomadcoders.co

 

Comments