실습을 위해 next.js 프로젝트를 생성한다.
npx create-next-app@latest --ts next-sample
생성시 질의는 모두 No~~!
SSG - Static Site Generation 정적사이트 생성
빌드시 페이지를 생성한다.
-- 사용 함수
export const getStaticProps: GetStaticProps<P> = async(context) =>
pages/ssg.tsx 로 파일생성한다.
next.js 에서는 폴더/파일 구조로 tsx 파일을 생성하면 그대로 호출 주소가 된다.
즉, localhost:3000/ssg 로 호출 하면 이 페이지가 호출된다.
import { GetStaticProps, NextPage } from "next";
import Head from "next/head";
type SSGProps = {
message: string;
}
//typescript 이니까 페이지 정의는 NextPage로 한다.
//props 을 받아야 하니 SSGProps 로 정의
const SSG:NextPage<SSGProps> = (props) => {
const { message } = props;
return (
<div>
<Head>
<title>Static Site Generation</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<main>
<p>이 페이지는 정적 사이트 생성을 통해 빌드시 생성된 페이지입니다.</p>
<p>{message}</p>
</main>
</div>
)
}
//typescript 이니 역시 리턴값을 정의
//getStaticProps는 GetStaticProps 타입이다.
export const getStaticProps: GetStaticProps<SSGProps> = async (context) => {
const timestamp = new Date().toLocaleString();
const message = `${timestamp}에 getStaticProps가 실행됐습니다.`
console.log(message)
//여기에서 반환한 props를 기반으로 페이지 컴포넌트를 그린다.
return {
props: {
message,
}
}
}
export default SSG;
getStaticProps 를 이용해, 미리 생성해서 props 값들을 주입한다.
export 로 해당 함수는 써야하고 async 와 함꼐 정의 해야한다. ( 여기서 쓴 모양을 외우자! )
하지만 테스트시에는 계속 업데이트가 되는데, 개발환경에서는 요청시 계속 페이지를 생성하기 때문이다.
-- 사용 함수
export const getStaticPaths: GetStaticPaths = async() =>
pages/posts/[id].tsx 로 생성한다. 저번 샘플 실습할때보고 있지만, 참 적응 안되는 구조다.
어쨌든 [id].tsx 는 직관적으로 대괄호 안의 값이 대체가 되는거구나! 하고 알 수 있다.
이번 샘플은 블로그 같이 글이 써질때 모든 페이지를 자동 생성되게 하기위한 구조이다.
그래서 테스트 접속은
localhost:3000/posts/1 <-- 이렇게 접근하면되는거다!
import { GetStaticPaths, GetStaticProps, NextPage } from "next"
import Head from "next/head"
import { useRouter } from "next/router"
import { ParsedUrlQuery } from "querystring"
type PostProps = {
id: string
}
const Post: NextPage<PostProps> = (props) => {
const {id} = props
const router = useRouter()
//폴백 페이지용 표기
if(router.isFallback){
return <div>Loading...</div>
}
return (
<div>
<Head>
<title>Create Next App</title>
</Head>
<main>
<p>이 페이지는 정적 사이트 생성을 통해 빌드 시 생성된 페이지 입니다.</p>
<p>{`/posts/${id}에 대응하는 페이지입니다`}</p>
</main>
</div>
)
}
//경로 pageds/posts/[id] 에 따라 id 값을 반환한다.
export const getStaticPaths: GetStaticPaths = async() =>{
const paths = [
{
params: {
id: '1',
}
},
{
params: {
id: '2',
}
},
{
params: {
id: '3',
}
}
]
//fallback:false 하면 정의된 페이지 외에는 404표기
return {paths, fallback: false}
}
//typescript 이니까! 파라미터 타입정의
interface PostParams extends ParsedUrlQuery{
id: string
}
//getStaticPaths 실행후, 각페이지별로 getStaticProps가 호출되어서, 정적 페이지 생성
export const getStaticProps: GetStaticProps<PostProps, PostParams> = async(context) => {
return {
props: {
id: context.params!['id']
}
}
}
export default Post
마지막에 있는 !(느낌표-exclamation mark) 는 확장 할당 어썬셜(Definite Assignment Assertions)로, null 오류가 발생할 수 있는곳에 이건 무조건 값있으니 걱정마라! 라고 해줄때 쓰는 부호이다.
react 를 확실히 알고 Next.js 에 접근하는게 맞는거 같으면서도, 먼가 어렵다 ㅡㅜ;
게다가 TypeScript 때문에 더 어렵다...
반복반복반복!!!