프론트엔드/Next.JS
Next.JS 타입
학습하는 청년
2024. 5. 24. 16:40
최종 수정 : 2024-05-24
Next.js에서 특별하게 사용하는 타입은 많지 않기에 공식문서만 읽어보아도 충분하다.
https://nextjs.org/docs/pages/building-your-application/configuring/typescript
커스텀 App
_app.tsx 파일에서는 웹 사이트 전체에 공통적으로 렌더링 되는 App이라는 컴포넌트를 만든다. 이 컴포넌트의 Props 형태는 정해져 있다. AppProps라는 타입을 next/app 패키지에서 불러와서 사용하면 된다.
import Head from 'next/head';
import { AppProps } from 'next/app';
import Header from '@/components/Header';
import '@/styles/global.css';
export default function App ({ Component, pageProps }: AppProps) {
return (
<>
<Head>
<title>Codeitmall</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<Header />
<Component {...pageProps} />
</>
);
}
프리 렌더링
정적 생성
Next.js에서는 빌드 시점에 리액트 코드를 미리 렌더링 해둘 수 있는데, 이를 정적 생성(Static Generation)이라고 한다.
import Image from 'next/image';
export async function getStaticPaths () {
const res = await fetch('https://learn.codeit.kr/api/codeitmall/products/');
const data = await res.json();
const products = data.results;
const paths = products.map((product) => ({
params: { id: String(product.id) },
}));
return {
paths,
fallback: true,
};
};
export async function getStaticProps(context) {
const productId = context.params ['id'];
let product;
try {
const res = await fetch(`https://learn.codeit.kr/api/codeitmall/products/${productId}`);
const data = await res.json();
product = data;
} catch {
return {
notFound: true,
};
}
return {
props: {
product,
},
};
}
export default function ProductPage({ product }) {
return (
<div>
<h1>{product.name}</h1>
<Image
src={product.imgUrl}
width="480"
height="480"
alt={product.name}
/>
</div>
);
}
Next.js에서는 기본적으로 화살표 함수로 만든 다음에 GetStaticPaths, GetStaticProsp 타입을 지정하는 것을 권장한다.
why?
import { GetStaticPaths, GetStaticProps } from 'next';
// ...
export const getStaticPaths: GetStaticPaths = async () => {
// ...
return {
paths,
fallback: true,
};
};
export const getStaticProps: GetStaticProps = async (context) => {
// ...
return {
props: {
product,
},
};
}
// ProductPage
interface Props {
product: Product;
}
export const getStaticProps: GetStaticProps<Props> = async (context) => {
// ...
return {
props: {
product,
},
};
};
export default function ProductPage({ product }: Props) {
return (
<div>
<h1>{product.name}</h1>
<Image
src={product.imgUrl}
width="480"
height="480"
alt={product.name}
/>
</div>
);
}
서버사이드 렌더링
Nexr.js 서버에 리퀘스트가 들어올 때마다 렌더링을 해서 보내준다.
import Image from 'next/image';
export async function getServerSideProps(context) {
const productId = context.params['id'];
let product;
try {
const res = await fetch(`https://learn.codeit.kr/api/codeitmall/products/${productId}`);
const data = await res.json();
product = data;
} catch {
return {
notFound: true,
};
}
return {
props: {
product,
},
};
}
export default function ProductPage({ product }) {
return (
<div>
<h1>{product.name}</h1>
<Image
src={product.imgUrl}
width="480"
height="480"
alt={product.name}
/>
</div>
);
}
정적 생성에서 했던 방식과 동일하게 화살표 함수로 변경한다음 진행한다.
interface Props {
product: Product;
}
export const getServerSideProps: GetServerSideProps<Props> = async (context) => {
// ...
return {
props: {
product,
},
};
};
export default function ProductPage({ product }: Props) {
return (
// ...
);
}
API 라우트
리퀘스트와 스프론스 타입을 지정하면 된다.
import type { NextApiRequest, NextApiResponse } from 'next'
export default function handler(req: NextApiRequest, res: NextApiResponse) {
// ...
}