Next.js 프레임워크의 이해

강호준2024-07-13
문법Next.jsNext.js 14취준포폴

공식문서

Example Image

Getting Started: Project Structure

packege.json 생성

  • npm init -y

패키지 설치

  • npm install react next react-dom

실행

  • package.json에서 scripts에서 dev 모드 next dev 바인딩으로 수정
  • npm run dev 하면 next js 기반으로 개발자 모드 실행

app/url/page.tsx

  • 기본적으로 app 디렉토리에서 url 이름으로 폴더를 생성한 뒤 page.tsx 이름으로 파일을 생성하여 아래의 export defalut가 반드시 있어야 한다. 이름으로 찾기 때문에 next는 이렇게 해줘야함ㅇ
export default function Tomato(){
    return <h1>NextJs!</h1>
}

이름이 정해져 있는 파일들

page.tsx

  • ui로 인식하는 하나의 메인 파일ㅇㅇ

디렉토리(url)

  • page파일이 있는 폴더를 하나의 url로 인식함.

not-found.tsx

  • 이건 오류 페이지임 ㅇㅇ 제일 상위에 1개만 만들어도 됨.
  • 이건 네비게이션임.

layout.tsx

  • 이거 layout임 baseComponents와 똑같음. 여기서 푸터랑 이거저거 하기 ㅇㅇ
  • 해당 파일은 해당 디렉토리의 baseComponents임.
  • 이를 테면 root에 하면 root 디렉토리의 베이스 컴포넌트가 되지만, about us 디렉토리에 넣으면 root에선 보이지 않고 about us의 하위 디렉토리부터 about us까지의 베이스 컴포넌트가 되는 것임ㅇ

loading.tsx

  • 로딩 페이지 만들기
  • 이건 page와 항상 같은 레벨에 있어야 함.

error.tsx

  • 에러 페이지
  • 부모 page와 같은 레벨에 존재 부모 page가 사용한 자식의 함수에서 에러가 발생해도 부모 페이지에선 멀쩡히 작동하고, 자식 부분에서 에러 발생
  • 항상 use client 여야 함.

함수 & 기능

usePathname()

  • 현재 경로명을 가져오는 함수 CSR에서만 사용 가능
  • 페이지 상단에 “use client” 붙여야 함.

use client

  • 모든 페이지(SSR, CSR)는 백엔드 단에서 먼저 렌더링
  • 이후 CSR들만 js 파일을 계속 렌더 시켜줌
  • defalut 값은 SSR인데 CSR을 그럼 어떻게 설정하냐? → ‘use client’ 최상단에 바인딩
  • 우린 hydratin 하게 갈 예정 CSR을 꼭 필요한 부분에만 사용하면 시간을 굉장히 아끼는 거임 ㅇㅇ
  • client 사이드에서 server 사이드로 가는 건 불가능
  • 즉, 메인이 되는 page.tsx는 client 없이 서버 사이드에서만 돌린다면 해당 파일의 js는 클라이언트로 넘어가는 일이 없음. 여기서 DB와 통신하고 api key를 사용해도 보안에 전혀 문제가 없다는 사실

디렉토리명 ()로 감싸주기

  • (home) → 이렇게 하면 그룹화임 url로 바꿔주는 것이 아닌 그저 그룹으로 묶어줌ㅇㅇ

Meta Data

  • client에게 주는 정보임ㅇㅇ 이걸 이용해서 SEO에 좋은 영향을 미칠 수 있음.

  • 이걸 잘 써야 하는데, 내가 생각한 걸론 블로그의 유저 마다 타이틀 및 배너 마다 타이틀과 디스크립션을 다르게 줄 수 있음. 정말 어썸함.

  • 아래는 메인 레이아웃의 어썸한 코드 각각 page.tsx에서 title만 바인딩 해주면 어썸하게 변경

export const metadata :Metadata = {
  title: {template: "%s | Next Movies",
    default: "Loading...",
  },
  description: 'The Best Movies on the best',
};

디렉토리에 대한 정보

  • 소괄호 → 디렉토리로서 사용하겠다는 의미임. url 취급 x
  • 대괄호 → 동적 라우터로 사용하겠다는 의미임. 상위 url/뭐가 오든 동적으로 인정
  • 아래 같은 경우 /movies/아무거나
  • 괄호 없음. → 정적 라우터로 사용하겠다는 의미임.

Untitled

동적 라우팅

  • 대괄호 디렉토리를 쓰면 됨.
  • 아래와 같이 props로 받은 map 데이터를 살펴보면 디렉토리명인 id를 키로 url이 전송된 것을 확인할 수 있음. 이걸 이용해서 DB와 연동하고 재미있는 작업을 많이 할 수 있을 것 같음.

Untitled

Untitled

  • 이런 식으로 url의 region, page 등 searchParams로 받아올 수 있음. 이걸 이용해서 또 재미있는 것들 할 수 있을 것 같음. 이를 테면 내 블로그 글을 page로 해서 읽을 수 있게 하거나 하는 등ㅇㅇ

Untitled

Untitled

CSR에서의 fetch → 일반적인 프레임워크는 이렇다

  • useState로 관리 / Loding Page의 상태 등을 직접 관리 해야함.
  • client 방식이기에 API KEY가 노출 될 위험이 있음.
'use client';

import { useEffect, useState } from "react";

// export const metadata = {
//     title: "Home",
//   }

export default function Page(){
    const [isLoading, setIsLoading] = useState(true);
    const [movies, setMovies] = useState();
    const getMovies = async () => {
        const response = fetch("https://nomad-movies.nomadcoders.workers.dev/movies");
        const json = await (await response).json();
        setMovies(json);
        setIsLoading(false);
    }
    useEffect(() => {
        getMovies();
    })
    
    return (
        <div>
            {isLoading? "Loading...." : JSON.stringify(movies)}
        </div>
    )
}

SSR에서의 fetch

export const metadata = {
    title: "Home",
  }

const URL = "https://nomad-movies.nomadcoders.workers.dev/movies";

async function getMovies() {
    return fetch(URL).then(response => response.json());
}

export default async function HomePage(){
    const movies = await getMovies();
    return (
        <div> {JSON.stringify(movies)} </div>
    )
}

fetch에서의 비동기 처리(구버젼)

  • fetch를 하는데 순차적으로 이루어지면 문제가 있음 ㅇㅇ
  • 만약에 아래처럼 두개의 함수가 있으면 순차적으로 실행이 아니라 동시에 가져와야 함ㅇㅇ

Untitled

  • 그럴 때 바로 이렇게 해야함
  • Promise.all 함수를 사용해서 배열 형태로 묶어서 await를 한번에 주는 것 그러면 동시에 시작

Untitled

fetch에서의 비동기 처리(개정판)

  • 위에서 한 방식은 좋은 방식일지도 모르나, 모든 함수가 끝나야만 실행이 됨. 경우에 따라 좋을 수도 있음.
  • 동시에 병행으로 진행하고 먼저 된 부분만 보여주면 나머지도 기다리기 좋지 않을까?
  • 이런 생각이 들었다면 Suspense를 사용해야함.
  • Suspense는 React에서 제공하는 강력한 기능

Untitled

  • 아래와 같이 컴포넌트 디렉토리에 따로 만들어두기

Untitled