Next.js 입문해보기

채희태·2022년 8월 31일

SSR의 앱을 만들어보고 싶다는 생각이 들었고,
가장 많이 쓰이는 프레임워크인 Next.js 에 입문해보았다.


Next.js를 알아보자!

next.js는 프레임워크이기 때문에 정해진 규칙에 따라 코드를 작성해야 한다.
라이브러리인 react.js와 같이 자유롭게 원하는 방식으로 코드를 작성하는것과는 상반된다.

next.js는 정적으로 생성되는 pre-render이다.

  • CSR 브라우저에 div태그 하나의 빈 html을 보냄 -> 브라우저에서 js를 다운로드하고 react.js를 실행함 -> 모두 fetch 된 후에 렌더링함
  • SSR 브라우저에 pre-rendering된 실제 html을 보냄 -> 브라우저에서 js를 다운로드하고 react.js를 실행함 -> 모두 fetch 된 작동 가능한 앱 렌더링함

pre-render로 인해 첫 페이지가 작동을 하진 않지만 렌더링이 완성된 html을 유저가 빠르게 받아 볼 수 있으며 SEO에서 좋은 성능을 갖는다.

설치하기

npx create-next-app

pages

router를 사용할 필요없이 pages폴더 안에 파일을 생성하면 파일명으로 된URL 페이지가 생성된다.
이 때, 컴포넌트를 꼭 export default해야 생성된다.

routing

a 태그를 사용하면 전체 페이지가 새로고침 되기 때문에,
클라이언트 사이드 네비게이션인 Link컴포넌트를 사용한다.
a 태그를 감싸는 이유는 class와 style을 지정할 수 있기 때문이다.

useRouter훅을 사용해 router를 연결해줄 수 있다.

import Link from "next/link";
import { useRouter } from "next/link";

export default const NavBar = () => {
  const router = useRouter();
  const { pathname } = router;
  return (
    <Link href="/">
      <a 
        style={{ color: pathname === '/navbar' ? 'red': 'blue'}}
        className={{ pathname === '/navbar' ? 'navbar' : '' }}
      >
        Home
      </a>
    </Link>
  )
}

_app

next.js는 다른 파일을 렌더링하기 전에 _app.js 파일을 먼저 렌더링한다.

만약 About컴포넌트를 렌더링 한다면 Component가 About으로 바뀌는 것이며, 이 방법으로 About컴포넌트가 렌더링 된다.

_app 파일에 다른 컴포넌트를 넣으면 모든 페이지에서 렌더링 된다.

import '../styles/globals.css'
import '../components/NavBar'

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

export default MyApp

Next.js를 구성해보기

Layout

components 폴더에 Layout 파일 생성!
Layout은 _app파일의 코드를 간소화 하기 위해 작성하는 파일이다.

모든 페이지에서 렌더링할 부분을 Layout에서 구성하고 Children을 사용해 Layout으로 _app을 감싸준다.

Layout.js

import React, { Children } from 'react'

function Layout({ Children }) {
  return (
    <div>{Children}</div>
  )
}

export default Layout

_app.js

import Layout from '../components/Layout'
import '../styles/globals.css'


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

export default MyApp

Seo

components 폴더에 Seo 파일 생성!
Seo 파일을 만들어서 Head를 구성한다. Head는 인터넷 파일창의 탭 부분이다.

Head를 사용할 파일에서 Seo컴포넌트를 불러와 props로 title을 넘겨준 후 Head에서 받아준다.

import React from 'react'
import Head from 'next/head'

function Seo({ title }) {
  return (
    <Head>
      {title}
    </Head>
  )
}

export default Seo
import Seo from '../components/Seo'
import styles from '../styles/Home.module.css'

export default function Home() {
  return (
    <div>
      <Seo title="home"/>
      this is Home!
    </div>
  )
}

redirect, rewrite

redirect는 URL을 바꿔주며 유저가 이를 인식할 수 있다.

redurect는 서버가 mask하여 URL을 바꿔 주므로 유저가 이를 인식할 수 없다.
이 점을 이용하여 API KEY 등을 숨겨줄 수 있다.

const nextConfig = {
  reactStrictMode: true,
  async redirects() {
    return [
      {
        source: "/old-form",
        destination: "/new-form",
        permanent: false,
      }
    ]
  },
  async rewrite() {
    return [
      {
        source: "/api/movie",
        destination: "/basedURL/APIKEY",
        //fetch를 할 때, URL을 위의 /api/movie를 사용하면 된다.
      }
    ]
  }
}

module.exports = nextConfig

getServerSideProps

서버에서 데이터를 pre-rendering해서 props를 리턴해 준다.
그리고 컴포넌트에서는 prop로 그 데이터를 받아와서 초기 HTML을 구성한다.
이를 통해 HTML의 뼈대만 갖춰주는 CSR과는 달리 SSR에서는 전체적으로 초기 렌더링을 완성한 HTML을 갖추는 것이다.
HTML의 소스코드를 살펴보면 props로 모든 데이터가 넘겨진 후 코드를 구성하고 있음을 볼 수 있다.

이 때, api키 등을 가려줄 필요는 없다. 서버에서 처리가 되기 때문에 유저는 볼 수 없기 때문이다.

import Seo from '../components/Seo'
import styles from '../styles/Home.module.css'

export default function Home({ result }) {
  return (
    <div>
      <Seo title="home"/>
      {console.log(result)}
    </div>
  )
}

export async function getServerSideProps() {
  const res = await fetch("/basedURL/APIKEY")
  const result = res.json()
  return {
    props: {
      result,
    },
  };
}

Dynamic Routes

중첩 라우터

/about/me, /about/user과 같이 중첩되는 URL이 필요할 경우
about 폴더 생성 -> me.js, user.js 파일을 생성한다.

변수 라우터

/about/124512323과 같이 변수id가 URL에 들어가야 할 경우
[id].js 파일을 생성한다.

profile
기록, 공부, 활용

0개의 댓글