[TIL] Next.js - 2

ohoho·2024년 11월 14일

슬기로운스터디

목록 보기
44/54

오늘 공부한것 & 기억할 내용

Data fetch

  • server component에서 fetch를 하게 되면 useEffect, useState, 로딩상태 구현등 불필요한 코드가 필요없다
  • server component에서 NextJS가 fetch한것을 기억한다(처음 fetch만 api에 요청을 하는것)
  • server component에서 data fetch를 하면 사용자가 화면에서 해당 data를 볼 수 없어 안전성이 보장된다.(api key등 볼 수 없다)
  • 같은 폴더에 loading.tsx파일을 만들면 ui적인 일부분(layout.tsx 등)만 미리 보여지고 data가 fetch되기 전까지 loading.tsx가 보여진다.
export const API_URL = "";

async function getMovies() {
    // await new Promise((res)=>setTimeout(res,1000))
    const json  = await(await fetch(API_URL)).json();
    return json
}

export default async function HomePage(){
    const movies = await getMovies();

Promise.all

  • 여러 api를 fetch할때 async를 사용하면 순차적으로 실행되기에 동시에 시작되게 하기 위해 Promise.all()를 사용하여 병렬적으로 data fetch를 한다
  • 문제점 : 동시에 fetching을 하는 컴포넌트들 중 한개가 5분이 넘는 시간이 걸린다면 모든 컴포넌트들의 ui가 그때까지 보이지 않는다.
const [movie, videos] = await Promise.all([getMovie(id),getVideo(id)])

Suspense

  • 여러개의 컴포넌트(fetch data)가 있을경우 fetch된 순차적으로 컴포넌트 UI를 보여준다.(Suspense로 감싸준다.)
  • Suspense가 데이터를 fetch하기 위해 안의 컴포넌트를 await한다.(컴포넌트의 fetch가 끝나면 UI를 보여준다)
  • 컴포넌트가 fetch되기전 Suspense의 fallback을 사용하여 await될 동안 보여질것을 넣어준다
  • 컴포넌트 개별 loading문구를 보여줄 수 있다.
<Suspense fallback={<h3>Loading...  </h3>}>
  <MovieInfo id={id}/>
</Suspense>
<Suspense>
  <MovieVideo id={id}/>
</Suspense>

error

  • data fetch가 에러났을경우 같은 위치에 error.tsx을 만들면 nextJS가 자동으로 error컴포넌트를 불러온다.(파일에 컴포넌트 자식요소들이 있을경우 error.tsx가 영향을 끼쳐서 자식요소에서 error가 나도 error.tsx가 불러와진다)

global css

  • 공통 css는 공통으로 사용되는 layout.tsx에 넣어준다
import "./styles/global.css"

css Module

  • 1개의 파일에 해당하는 1개의 css 파일을 만드는 방식(모든 css의 이름 끝에는 module.css가 들어가야한다)
  • 원하는 module.css생성후 파일에 import한 후 className을 사용해 코드를 적용한다.
  • 일반적인 태그를 단독으로 사용할 수 없다(단독 사용은 global.css에서만 가능)
//Home.tsx
import styles from './Home.module.css'

<div className={style.wrap}

//Home.module.css
wrap{}
wrap p{} //클래스 네임이 앞에 있으면 태그 사용 가능 
  • NextJs에서 링크 이동을 할때는 두가지를 사용할 수 있다.
  • router를 사용할때는 next/navigation으로 사용한다.(router를 사용하니 "use client"사용)
  • Link에 prefetch를 사용하게 되면 해당페이지로 이동하기전에 미리 데이터가 prefetch되어있다
//router
import { useRouter } from "next/navigation";

const router = useRouter();
const onClick = () => {
  router.push(`/movie/${id}`);
};
<img src={poster_path} alt={title} onClick={onClick} />
  
//Link
<Link href={`/movie/${id}`}>{title}</Link>

generateMetadata

  • 동적인 페이지의 metadata를 변경할때 사용
  • 최신 NextJs는 data를 캐싱하니 같은 함수를 여러번 호출해도 상관이 없다(getMovie())
export async function getMovie(id:string){
    const json = await(await fetch(`${API_URL}/${id}`)).json();
    return json
}
//==========================================================
interface IParams{
    params: { id: string };
}

export async function generateMetadata({params:{id}}:IParams) {
    const movie = await getMovie(id)
    return {
        title:movie.title 
    }
}

배운점 & 느낀점

data fetch를 server component에서 하면 보안에 안전하다는 것을 배웠고, data가 여러개일때 promise.all를 사용한 fetch와 suspense를 사용한 fetch를 배웠고 둘의 차이점도 알게 되었다.
또 동적인 페이지의 head title 그에 맞춰 동적으로 변할 수 있는 generateMetadata도 배웠는데 편리한거 같다.
아직은 익숙하지 않지만 크게 어려운점은 없는거 같은데 더 많은것을 해봐야 알거같다.

0개의 댓글