본문 바로가기
IT/javascript

[TS]Next.js 기초 - SSG

by 가능성1g 2024. 6. 22.
반응형

실습을 위해 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 때문에 더 어렵다... 

 

반복반복반복!!!

반응형