Next.js

박찬영·2024년 4월 20일
0
post-thumbnail

회사에서 Next 가 필요할 것 같아서 공부하면서 정리해 봅니다.
제 방식대로 정리한 거라 이해하기 힘들 수 있으니 양해 부탁드립니다.

Next.js

기본 지식

🐔 hydration

Next.js 는 hydration입니다. 단순 HTML 을 React application 으로 초기화 해줍니다.
/about ———> <Button>0</Button> ———> :) ———> <Button onClick={}>0</Button>
서버사이드 렌더링(SSR)을 통해 만들어 진 인터랙티브 하지 않는 HTML을
클라이언트 측 자바스크립트를 사용하여 인터랙티브한 리액트 컴포넌트로 변환하는 과정을 말합니다.

서버 환경에서 이미 렌더링된 HTML에 React를 붙이는 것

🐔 “use client”

이봐, 이 component 는 client 에서 interactive 해야해
이 components 는 hydrated 해야해!! 라고 알려주는 것입니다.

즉 client 측에서 관리해야 하는 코드가 있을 경우 사용합니다.
고맙게도 개발을 하다 use client 를 사용해 하면 next.js 에서 친절하게
오류로 실수를 알려줍니다.

"use client"

const Home = () => {
  const [data, setData] = useState(null);
  // client 측 관리를 해야 할 때 use client 사용
  ...
}

Server component 안에서 client component 를 가질수 있지만 반대는 불가능 합니다.
Server component 에 장점은 해당 컴포넌트 코드에 DB, 서버에서 불러오는 기능등 보안에 신경쓰지 않고 마음것 사용할 수 있다는 장점이 있습니다.

왜? Client 로 가서 실행하는게 아니라 서버에서 실행한 뒤에 html 로 넘겨주기 때문이죠.


Next.js 둘러보기

🐔 경로 설정하기

React 에서는 router-dom 라이브러리를 사용하지만 Next 에서는 그냥 폴더만 있으면 됩니다.

그대신 app 안에 있어야 합니다.

만약 sales 폴더 안에 page.tsx 말고 pages.tsx, home.tsx 같은 파일이있다면 sales 경로로 갔을때 다른 파일을 렌더링 할까요?? 결론은 아닙니다.
Next.js 는 page.tsx 만을 찾아서 렌더링 해줍니다.

랜더링
리액트를 사용할 때 자바스크립트로 개발하는데 그러한 함수형 컴포넌트들을 브라우저가 이해할 수 있는 HTML 로 변환해 주는 작업을 말합니다.


🐔 중첩 페이지

Navbar 처럼 공통 요소를 모든 페이지에 넣고 싶다면 layout.tsx 를 사용하면 됩니다.
하지만 home 이라는 페이지와 home 안에 상세 페이지만 Navbar 처럼 공통 요소를 넣고 다른 페이지는 적용하고 싶지 않다면 어떻게 해야 할까요??

그때 사용하는 방법이 중첩 페이지 입니다.

기본 골격


import React from 'react';

interface RootLayoutProps {
  children: React.ReactNode;
}

const RootLayout: React.FC<RootLayoutProps> = ({ children }) => {
  return (
    <div>
     {children}
    </div>
  );
};

export default RootLayout;

🐔 metadata

주어진 데이터의 의미, 구조, 형식, 처리 방법 등을 설명합니다.
웹 개발에서 메타데이터는 웹 페이지의 정보를 설명하고 검색 엔진이나 소셜 미디어 플랫폼이 페이지를 이해하고 적절하게 표시할 수 있도록 도와줍니다.

export const metadata = {
  title: 'Next.js',
  description: 'Generated by Next.js',
}

metadata 를 쓸 때 주의할 점은
페이지나 레이아웃만 메타데이터를 내보낼 수 있습니다.

Page.tsx , layout.tsx

또 서버 컴포넌트에만 있을 수 있고 클라이언트 컴포넌트에는 있을 수 없습니다.

또한 Next.js에는 향상된 SEO 및 웹 공유성을 위해 애플리케이션 메타데이터(ex: HTML head 엘리먼트 내의 meta 및 link 태그)를 정의하는 데 사용할 수 있는 메타데이터 API가 있습니다.

export const metadata:Metadata = {
  title: {
    template: "%s | Next Movies",
    default: "Loading..."
  },
  description: 'Generated by Next.js',
}

// 다른곳에서 
export const metadata:Metadata = {
  title: "not found"
}

🐔 라우트 그룹화 하기

폴더명으로 쉽게 개발하고 폴더를 그룹화하면 어떻게 해야 할까요??

정말 간단하게 구현할 수 있습니다.

예시 폴더 구조

(Home) -> page.tsx
(Shop) -> Shop -> page.tsx

🐔 params

http://localhost:3000/movies/123?county=kr&hobby=soccer

여기서 123?county=kr&hobby=soccer 이러한 정보들을 어떻게 가져올 수 잇을까요??

(Movies) -> movies -> [id] / page.tsx


🐔 Next.js 에서 데이터 가져오는법

next.js 에서는 데이터를 자동으로 캐싱해서 보관하는 기능을 가지고 있다.

import React from 'react';

export const metadata = {
  title: "Home"
}

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

async function getMovies() {
  const response = await fetch(URL);
  const data = await response.json();
  return data
}

const HomePage = async () => {

  const movies = await getMovies()

  return (
    <div>
      {JSON.stringify(movies)}
    </div>
  )
}

export default HomePage

근데 만약 저 getMovies 가 오래걸리면 어떻게 될까??
그때 해야 될 행동은 해당 폴더에 loading.tsx 를 만드는 것입니다.
next.js 는 단지 해당 데이터를 불러오는 파일이 포함되어 있는 폴더에 loading.tsx 만 만들어줘도 데이터를 불러오는 동안 loading.tsx 코드를 보여줍니다.


🐔 데이터 병렬 불러오기

import React from 'react';
import { URL } from '../../../(Home)/page';

const getMovie = async (id:string) => {
  const response = await fetch(`${URL}/${id}`);
  return response.json();
}

const getVideos = async (id:string) => {
  const response = await fetch(`${URL}/${id}/videos`);
  return response.json();
}

const Movies = async ({params: {id}}: {params: {id: string}}) => {
  const movie = await getMovie(id);
  const videos = await getVideos(id);
  return (
    <div>
      {movie.title}
      {videos.title}
    </div>
  )
}

export default Movies

이러한 코드가 있을 때 병렬적으로 실행하고 싶다면( 저 두 비동기 코드가 너무 오래걸리면) Promise.all 쓰면 된다.

  const movie = await getMovie(id);
  const videos = await getVideos(id);     // 이걸 아래 코드처럼

Const [movie, videos] = await Promise.all([getMovie(id), getVideos(id)])

🐔 Suspense

다른 곳에서 데이터 가져오고 차례차례 데이터가 온 순서대로 보여주고 싶다면
Suspense 를 사용하면 됩니다.

import React, { Suspense } from 'react';
import { URL } from '../../../(Home)/page';
import MovieVideos from '../../../../components/movie-videos';
import MovieInfo from '../../../../components/movie-info';


const Movies = async ({params: {id}}: {params: {id: string}}) => {
  return (
    <div>
      <Suspense fallback={<h1>Loading...</h1>}>
        <MovieInfo id={id}/>
      </Suspense>
      <Suspense fallback={<h1>Loading...</h1>}>
        <MovieVideos id={id}/>
      </Suspense>
    </div>
  )
}

export default Movies

// MovieVideos

import React from 'react';
import { URL } from '../app/(Home)/page';

const getVideos = async (id:string) => {
  const response = await fetch(`${URL}/${id}/videos`);
  return response.json();
}

// MovieVideos

const MovieVideos = async ({id}: {id: string}) => {
  const videos = await getVideos(id);
  return (
    <h6>{JSON.stringify(videos)}</h6>
  )
}

export default MovieVideos

🐔 CSS Modules

Next.js 에는 .module.css 확장자를 사용하여 CSS 모듈을 기본적으로 지원합니다.

Import styles from../styles/navigation.module.css”

<nav className={styles.nav}>
  <p>hello</p>
</nav>
profile
오류는 도전, 코드는 예술

0개의 댓글