npm init -y
npm install react@latest next@latest react-dom@latest
react vs. react-dom
- React는 UI와 다른 모든 것들을 구성하는 부분
- React-Dom은 그것을 브라우저의 Document Object Model(DOM)에 렌더하는 역할
next dev
라는 명령어를 실행하면프레임워크는 작성된 코드를 호출한다.
하지만 라이브러리는 사용자가 라이브러리 코드를 호출한다
react-router
- react-router의 작동방식은 url을 지정하고 Home이라는 컴포넌트 render를 요청하는 것
- 사용자가 그 url에 접근하면 home이라는 컴포넌트를 render함
/movies/:id
와 같이 동적 라우팅도 가능함
Client Side Rendering (CSR)
- react가 render되는 방식은 CSR
- 브라우저의 자바스크립트 엔진이 rendering 작업을 함
- rendering은 react code를 브라우저가 이해할 수 있는 html로 바꾸는 것
- Client(브라우저)는 JavaScript를 로드하고, 그 후에 JavaScript가 UI를 빌드함
- CSR 단점
- CSR로 된 페이지는 해당 페이지를 실행하기 위해서는 브라우저에 자바스크립트가 활성화되어있어야 함
- SEO 검색 엔진 최적화
Serverr Side Rendering (SSR)
- Next.js를 사용하면 자동적(default)으로 SRR이 됨
- 브라저는 자바스크립트가 로드될 때까지 기다릴 필요가 없음. 왜냐하면 이미 화면에 표시할 html을 갖고 있기 때문
- Next.js는 서버, 즉 백엔드에서 application을 render함. 그걸 브라우저 request에 대한 response로 줌
- next.js에 작성된 모든 컴포넌트(클라언트/서버 컴포넌트 모두), 페이지들은 우선 SRR이 됨
import { Metadata } from "next";
import { API_URL } from "../../../(home)/page";
export const metadata: Metadata = {
title: 'movie detail',
}
type Props = {
params: {
id: string;
};
};
async function getMovieDetail(id:string) {
console.log(`fetching movies: ${Date.now()}`)
await new Promise((resolve)=>setTimeout(resolve, 5000))
const response = await fetch(`${API_URL}/${id }`);
return response.json();
}
async function getVideos(id:string) {
console.log(`fetching videos: ${Date.now()}`)
await new Promise((resolve)=>setTimeout(resolve, 5000));
try {
const response = await fetch(`${API_URL}/${id}/videoss`);
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
} catch(e) {
return {result: null}
}
}
export default async function MovieDetail({ params }: Props) {
console.log(`fetching start: ${Date.now()}`)
// const movie = await getMovieDetail(params.id);
// const videos = await getVideos(params.id);
const [movie, videos] = await Promise.all([getMovieDetail(params.id), getVideos(params.id)]);
console.log(`fetching end: ${Date.now()}`)
console.log(">> videos", videos)
return (
<div>
<h1> {movie.title}</h1>
<div>{JSON.stringify(movie)}</div>
</div>
);
}
import { Metadata } from "next";
import MovieVideos from "../../../../components/movie-videos";
import MovieInfo from "../../../../components/movie-info";
import { Suspense } from "react";
export const metadata: Metadata = {
title: 'movie detail',
}
type Props = {
params: {
id: string;
};
};
export default async function MovieDetail({ params }: Props) {
return (
<div>
<Suspense fallback={<h6>loading movie info</h6>}>
<MovieInfo id={params.id} />
</Suspense>
<Suspense fallback={<h6>loading movie videos</h6>}>
<MovieVideos id={params.id} />
</Suspense>
</div>
);
}
npx create-next-app@latest