본문 바로가기
Frontend/Next.js

[Next.js] Next.js 기본

by 디스코비스킷 2024. 1. 17.
반응형

Nextjs 기본

NextJS 란?

(리액트는 라이브러리, Next.js는 프레임워크이다. )
React의 SSR(Server Side Rendering)을 쉽게 구현할 수 있게 도와주는 간단한 프레임워크이다. 리액트로 개발할때 SPA을 이용하며 CSR(Client Side Rendering)을 하기때문에 좋은점도 있지만 단점도 있다. 검색엔진최적화(SEO)에 취약하다는 것이다. CSR을 하면 첫페이지에서 빈 html을 가져와서 JS파일을 해석하여 화면을 구성하기때문에 포털검색에 거의 논출될 일이 없다.(크롤링 안됨)

하지만 Next.js에서는 Pre-Rendering을 통해서 페이지를 미리 렌더링하며 완성된 HTML을 가져오기 때문에 사용자와 검색엔진 크롤러에게 바로 렌더링된 페이지를 전달 할 수 있게 된다.

리액트에서도 SSR를 지원하지만 구현하기에 굉장히 복잡하기 때문에 Next.js를 통해서 이문제를 해결할 수 있다.

Server Side Rendering

  • 클라이언트 대신 서버에서 페이지를 준비한 원리.
  • 원래 리액트에서는 CSR을 하기때문에 서버에 영향을 미치지 않고, 서버에서 클라이언트로 응답해서 보낸 html도 거의 비어있다.
    👉 이 방식은 서버에서 데이터를 가져올 때 지연 시간 발생으로 UX 측면에서 좋지 않을 수 있다.
    👉 검색엔진에 검색 시 웹 크롤링이 동작할 때 내용을 제대로 가져와 읽을 수 없기에 SEO에 문제가 됨.
  • Next.js에서는 SSR을 이용하므로 사용자와 검색엔진 크롤러에게 바로 렌더링이 된 페이지를 전달 할 수 있어서 UX, SEO에 좋은 영향을 준다.

설치 방법

npx create-next-app@latest
yarn create next-app

npx create-next-app ./ --typescript 타입스크립트 템플릿 사용

NextJS 기본 파일 구조

pages

  • 이 폴더 안에 페이지 생성
  • index.ts가 처음 "/" 페이지
  • _app.tsx는 공통되는 레이아웃을 작성함. 모든 페이지에 공통으로 들어가는 걸 넣어주려면 여기에 넣는다. url을 통해 특정 페이지에 진입하기 전 통과하는 인터셉터 페이지다.
  • 만약 about이라는 페이지를 만드려면 pages안에 about.tsx를 생성.

public

  • 이미지같은 정적static 에셋 보관

styles

  • 스타일링 처리해주는 폴더

next.config.js

  • Nextjs는 웹팩을 기본 번들러로 사용
  • 그래서 웹팩에 관한 설정들을 이파일에서 해줄 수 있다.

Pre-rendering

NextJS는

모든 페이지를 pre-render한다.

pre-render 테스트 하는방법

Data Fetching

NextJS에서 데이터를 가져오는 방법은 여러가지가 있다.
보통 리액트에서 데이터를 가져올때 useEffect안에서 가져온다. 하지만 Nextjs에서는 다른방법을 사용해서 가져온다.

  • getStaticProps: Static Generation으로 빌드할때 데이터를 불러온다.
  • getStaticPaths: Static Generation으로 데이터에 기반하여 pre-render시 특정한 동적 라우팅 구현(pages/post/[id].js)
  • getServerSideProps: SSR로 요청이 있을때 데이터를 불러온다.

getStaticProps

getStaticProps 함수는 페이지의 리퀘스트 경로에 따라 데이터를 가져옵니다. 따라서, 페이지별로 다른 데이터를 가져올 수 있습니다.

import React, { useState } from 'react';

const MyPage = ({ data }) => {
  const [name, setName] = useState('');

  if (data) {
    name = data.name;
  }

  return (
    <div>
      <h1>My Page</h1>
      <p>Name: {name}</p>
    </div>
  );
};

// getStaticProps 함수를 사용하여 데이터를 가져옵니다.
export const getStaticProps = async () => {
  const response = await fetch('https://api.example.com/data');
  const data = await response.json();

  return {
    props: {
      data,
    },
  };
};

export default MyPage;

getStaticProps를 사용해야할 때

  • 페이지를 렌더링하는 데 필요한 데이터는 사용자의 요청보다 먼저 build시간에 필요한 데이터를 가져올 때
  • headless CMS에서 데이터를 가져올 때
  • 데이터를 공개적으로 캐시할 수 있을 때(사용자별 아님)
  • 페이지는 미리 렌더링되어야 하고(SEO의 경우) 매우 빨라야할 때.(getStaticProps는 성능을 위해 CDN에서 캐시할 수 있는 HTML 및 JSON 파일을 생성한다.)

getStaticPaths

getStaticPaths 함수는 페이지의 리퀘스트 경로와 함께 데이터의 경로를 정의한다. 따라서, 페이지별로 다른 데이터를 가져오거나, 데이터를 캐싱할 수 있습다.

  • 동적 라우팅이 필요할 때 getStaticPaths로 경로 리스트 정의, HTML에 build시간에 렌더링
  • Nextjs는 pre-render에서 정적으로 getStaticPaths에서 호출하는 경로를 가져온다.

paths

어떠한 경로가 pre-render될 지 결정한다.
만약 pages/posts/[id].js라는 이름의 동적 라우팅을 사용하는 페이지가 있다면 아래와 같이 된다.

return {
    paths: [
      { params: {id: '1'} },
      { params: {id: '2'} },
    ],
      fallback: ...
}

params

  • 페이지 이름이 pages/posts/[postId]/[commentId]라면, params는 postId와 commentId
  • 만약 페이지 이름이 pages/[...slug]와 같이 모든 경로를 사용한다면, params는 slug가 담긴 배열이어야한다. ['postId', 'commentId']

fallback

  • false라면 getStaticPaths로 리턴되지 않는 것은 모두 404페이지가 뜬다.
  • true라면 getStaticPaths로 리턴되지 않는 것은 404로 뜨지 않고, fallback페이지가 뜨게된다.
if(router.isFallback){
    return <div>Loading...</div>
}
import React, { useState } from 'react';

const MyPage = ({ data }) => {
  const [name, setName] = useState('');

  if (data) {
    name = data.name;
  }

  return (
    <div>
      <h1>My Page</h1>
      <p>Name: {name}</p>
    </div>
  );
};

// getStaticPaths 함수를 사용하여 데이터를 가져옵니다. 
// build time에 call됨 
export const getStaticPaths = async () => {
  const response = await fetch('https://api.example.com/paths');
  const data = await response.json();

  return {
    paths: data.paths.map((path) => ({
      pathname: path.pathname,
      component: MyPage,
    })),
  };
};

export default MyPage;

getServerSideProps

  • getServerSideProps 함수를 async로 export하면, Next는 각 요청마다 리턴되는 데이터를 getServerSideProps로 pre-render한다.

getServerSideProps를 사용해야 할 때
요청할 때 데이터를 가져와야하는 페이지를 미리 렌더해야 할 때 사용한다. 서버가 모든 요청에 대한 결과를 계산하고, 추가 구성없이 CDN에 의해 결과를 캐시할 수 없기때문에 첫번째 바이틔까지의 시간은 getStaticProps 보다 느리다.

import React from 'react';

export async function getServerSideProps(context) {
  // Fetch data from an API or database
  const res = await fetch('https://api.example.com/posts');
  const posts = await res.json();

  return {
    props: {
      posts,
    },
  };
}

export default function Posts({ posts }) {
  return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  );
}

useQuery

useQuery 훅을 사용하여 클라이언트에서 데이터를 가져오면 페이지가 요청될 때마다 데이터를 가져온다. 따라서, 페이지가 처음 요청될 때는 데이터를 가져오는 데 시간이 걸릴 수 있다.

useQuery 훅은 다음과 같은 파라미터를 사용한다.

  • query: 데이터를 가져올 URL
  • options: 데이터 가져오기 옵션
  • callback: 데이터 가져오기 완료 후 실행되는 콜백 함수
import React, { useState } from 'react';

const MyPage = () => {
  const [name, setName] = useState('');

  // useQuery 훅을 사용하여 데이터를 가져옵니다.
  const { data, loading, error } = useQuery('https://api.example.com/data');

  if (loading) {
    return <div>Loading...</div>;
  } else if (error) {
    return <div>Error: {error.message}</div>;
  }

  if (data) {
    name = data.name;
  }

  return (
    <div>
      <h1>My Page</h1>
      <p>Name: {name}</p>
    </div>
  );
반응형

최근댓글

최근글

© Copyright 2023 jngmnj