Next.js 포트폴리오 만들기(4)

이성은·2023년 6월 20일

들어가기전에...정리..💡

  • 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

  • async await로 데이터 불러옴
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

  • 불러온 데이터를 map
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에 대해서도.... 좀더 공부해야 할것같다.🥲
profile
함께 일하는 프론트엔드 개발자 이성은입니다🐥

0개의 댓글