들어가기전에...정리..💡
- next.js의 12버전은 페이지 단위로 렌더링하고,
getStaticProps() 사용시 SSG/ISR, getServerSideProps() 사용시 SSR
- 13버전은 Server 컴포넌트/ Client 컴포넌트로 구분, 페이지단위가 아니라 컴포넌트 단위로 렌더링 방식을 규정
- app폴더 안에 있는 것은 기본적으로 서버컴포넌트
console.log()실행하면 브라우저 콘솔창엔 안 나오고, 터미널(서버)창에 나온다.
- 브라우저에서 제공하는 API 사용 못하고, 노드에서 제공하는 API사용해야 한다.
- 클라이언트 컴포넌트 : 정말 필요한 부분(클릭이벤트 같은거)만 컴포넌트를 만들어나간다.
- 'use client' 꼭꼭 명시해줘야해

현재 시도 한 것
- 홈에 각 카드에 프로젝트에 대한 데이터를 가지고 와서 홈에 띄우려함

next.js 비동기처리
파일 구조
- 메인 페이지에 Hello컴포넌트, FeaturedPosts컴포넌트를 보여줌
- 사용하는 데이터는 data파일안에 contents.json
- FeaturedPosts컴포넌트에서는 비동기로 데이터 불러옴
- PostsGrid.tsx는 프로젝트 카드들을 그리드로 나타내는 컴포넌트
- Card.tsx는 메인화면에 프로젝트를 설명하는 카드 하나
- 데이터불러오는 로직은 service폴더안에 contents.ts폴더안에 둬서 재사용이 가능하게 함
contents.ts
- Promise는 대기/완료/거부 상태를 가진다.
- 생성되었을때 완료 후에 어떤 값을 가지게 될지 제네릭을 통해 타입을 명시해줘야 한다.
- Node.js에서 제공하는 메소드를 사용
import { readFile } from "fs/promises";
import path from "path";
export type Post = {
title: string;
description: string;
date: Date;
path: string;
featured: boolean;
role: string;
stacks: string[];
};
export async function getAllContents(): Promise<Post[]> {
const filePath = path.join(process.cwd(), "data", "contents.json");
return readFile(filePath, "utf-8").then<Post[]>(JSON.parse);
}
FeaturedPosts.tsx
import React from "react";
import PostsGrid from "./PostsGrid";
import { getAllContents } from "@/service/contents";
export default async function FeaturedPosts() {
const contents = await getAllContents();
return (
<section className="my-4">
<h2 className="text-2xl font-bold ml-7 my-5">My projects</h2>
<PostsGrid contents={contents} />
</section>
);
}
PostsGrid.tsx
import { Post } from "@/service/contents";
import React from "react";
import Card from "./Card";
type Props = { contents: Post[] };
export default function PostsGrid({ contents }: Props) {
return (
<ul>
{contents.map((content) => (
<li key={content.path}>
<Card content={content} />
</li>
))}
</ul>
);
}
Card.tsx
import React from "react";
import { Post } from "@/service/contents";
import Link from "next/link";
import Image from "next/image";
type Props = { content: Post };
export default function Card({
content: { title, role, date, stacks, path, description },
}: Props) {
return (
<Link href={`/contents/${path}`}>
<Image
src={`/images/contents/${path}.png`}
alt={title}
width={450}
height={600}
/>
<div>
<span>{role}</span>
<time>{date.toString()}</time>
<h3>{title}</h3>
<span>{description}</span>
</div>
</Link>
);
}
- 타입스크립트를 좀 더 공부해야 할것같다.
- 또한 node에 대해서도.... 좀더 공부해야 할것같다.🥲