HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
🚀
개발 노트
/
🚀
아트집 - 예습
/
🏓
Next.js
🏓

Next.js

 
 

프레임워크

  • 기존 index, app 파일의 역할은 내부적으로 수행된다.
  • 라이브러리는 내가 코드를 사용한다. 프레임워크가 내가 작성한 코드를 사용한다.

pages

  • 파일명은 중요하다. url의 이름
  • pages 폴더의 컴포넌트명은 중요하지 않다.
  • 컴포넌트를 export default 해야 한다.
  • 404 페이지가 기본적으로 제공된다.
  • 아래와 같이 폴더를 만들 수도 있다.
    • notion image
  • React를 import할 필요가 없다. 확장자가 .tsx, .ts가 될 필요도 없다.
 

Static Pre Rendering

  • CSR: “브라우저가 자바스크립트(+ 리액트)를 가져오고, UI를 전부 만든다”
  • Next.js: 네트워크가 느리거나, 자바스크립트가 비활성화 되어 있어도 HTML을 볼 수 있다.
  • hydration: pre-rendering이 끝난 뒤, 자바스크립트(+ 리액트)가 로드되면 넘겨받아 동작한다.
    • 일반적인 React 앱이 된다.
  • Next.js는 React를 백엔드에서 동작시켜서 초기 페이지를 만들고 html에 넣어준다.
그렇기 때문에 유저는 자바스크립트(+ 리액트)가 로드되지 않았더라도 콘텐츠를 볼 수 있다.
 

Routing

  • a 태그를 사용하지 마라. 새로고침 되기 때문이다.
Link에는 스타일, 클래스 이름을 적용할 수 없다. 하위 a 태그는 가능하다.
 

Styles JSX

  • Next JS 고유의 방법
  • 명시한 스타일은 컴포넌트 내부로 스코프가 제한된다.
 

Custom App

App Component
“어떤 컴포넌트의 청사진과 같다”
_app.js
Next.js는 다른 페이지를 렌더링하기 전에 _app.js를 먼저 본다.
전역 스타일을 지정할 수도 있다.
 
_app에서는 모든 css를 import할 수 있다. 전역 스타일로 적용된다.
_app을 제외하고, 페이지나 컴포넌트 내에 css를 import하고 싶다면,
그것은 반드시 module이어야 한다.
 
NavBar를 보여주는 페이지가 있고, 그렇지 않은 경우가 있다.
이것은 어떻게 제어할까?
 

추가

  1. _app
서버 요청이 들어왔을 때 가장 먼저 실행되는 컴포넌트.
페이지에 적용할 공통 레이아웃의 역할을 한다.
전역적으로 사용하는 공통 데이터 등을 다루는 곳이다.
 
용도
  • page 이동 중 state를 유지하기 위해 (recoil state 등)
  • global css 추가
 
  1. _document
    1. _app 다음에 실행되며, 공통적으로 사용할 head나 body 태그 안에 들어갈 내용을 커스텀.
      즉, 모든 문서에 공통적으로 적용할 HTML 마크업을 커스텀 하는 곳이다.
용도
  • 폰트 import
  • charset, 웹 접근성 과니련 태그 설정
  • bootstrap, material UI 등 글로벌 커스텀 스타일 ㅅ트 로드
  • 글로벌 head 관리
 

패턴

  • Layout 컴포넌트
  • Head 컴포넌트 (내장)
 

Redirects

*을 붙이면 뒤에 붙는 경로들도 캐치할 수 있다.
.env를 gitignore에 포함시켜야 한다.

Rewrites

url이 변경되지 않는다.
 

타입스크립트

대응 타입들
  • getServerSideProps ⇒ GetServerSideProps
  • getStaticProps ⇒ GetStaticProps
  • getStaticPaths ⇒ GetStaticPaths
 
GetServerSideProps는 Promise를 반환해야 한다.
타입스크립트
 
아래와 같이 Promise를 반환하지 않으면 타입 에러가 발생한다.
notion image
 
async를 붙이는 것으로 간단히 해결할 수 있다.
async 함수는 암시적으로 Promise를 사용하여 결과를 반환하기 때문이다.
 
notion image
 
getServerSideProps는 데이터를 fetch할 때 외에도 사용할 수 있다.
 
import Link from "next/link" export default function NavBar() { return <nav> <Link href="/"><a>Home</a></Link> <Link href="/about"><a>About</a></Link> </nav> }
import Link from "next/link" import { useRouter } from "next/router" export default function NavBar() { const router = useRouter(); return <nav> <Link href="/"><a className={router.pathname === '/' ? 'active' : ''}>Home</a></Link> <Link href="/about"><a className={router.pathname === '/about' ? 'active' : ''}>About</a></Link> <style jsx>{style}</style> </nav> } const style = ` nav { background-color: tomato } .active { color: yellow } `;
import type { AppProps } from "next/app" import NavBar from "../components/NavBar" export default function App({ Component, pageProps }: AppProps) { return <div> <NavBar /> <Component {...pageProps} /> <style jsx global>{ ` h1 { color: red } ` }</style> </div> }
// next.config.js const API_KEY = process.env.API_KEY; // .gitignore에 포함시키기 const nextConfig = { reactStrictMode: true, async redirects() { return [ { source: '/contact', destination: '/form', permanent: false, }, { source: '/old-blog/:path', destination: '/new-blog/:path', permanent: false, }, ]; }, async rewrites() { return [ { source: '/api/movies', destination: `https://api.themoviedb.org/3/movie/popular?api_key=${API_KEY}`, }, ]; }, };
export type GetServerSideProps< P extends { [key: string]: any } = { [key: string]: any }, Q extends ParsedUrlQuery = ParsedUrlQuery, D extends PreviewData = PreviewData > = ( context: GetServerSidePropsContext<Q, D> ) => Promise<GetServerSidePropsResult<P>>