7/4 TIL

이세영·2024년 7월 5일
0
post-thumbnail

1. Next.js와 React를 사용한 포켓몬 상세 페이지 구현

주요 기능

  • 포켓몬 데이터를 API로부터 비동기적으로 가져와 화면에 렌더링
  • 포켓몬의 한국어 이름, 이미지, 타입, 능력, 신장, 체중 및 능력치를 표시
  • 타입에 따라 다른 배경색을 적용하여 시각적인 구분

코드 분석

1. 데이터 가져오기

import { fetchPokemonData } from "@/apis/pokemon";
  • fetchPokemonData 함수를 사용하여 특정 포켓몬의 데이터를 API로부터 가져옴.

2. 타입별 색상 정의

const typeColors: { [key: string]: string } = {
  // 타입별 색상 매핑
};
  • 포켓몬 타입에 따라 다른 색상을 적용하기 위해 색상 값을 객체 형태로 정의.

3. 컴포넌트 구조

const PokemonDetailPage = async ({ params }: { params: { id: string } }) => {
  const pokemonData = await fetchPokemonData(params.id);
  • PokemonDetailPage는 Next.js의 페이지 컴포넌트로, 비동기 함수를 사용하여 포켓몬 데이터를 가져옴.
  • params.id를 통해 동적 라우팅으로 포켓몬의 ID를 받아옴.

4. 페이지 레이아웃

return (
  <div className="flex flex-col items-center p-4 bg-[#f8f5f2] ... font-ramche">
    ...
  </div>
);
  • 페이지 전체의 레이아웃을 설정. 포켓볼 이미지를 배경으로 설정하고, 폰트 스타일을 지정.

5. 포켓몬 기본 정보

<div className="bg-white shadow-md rounded-lg p-6 w-full max-w-md">
  <div className="flex justify-between items-center mb-4">
    <h1 className="text-2xl font-bold">{pokemonData.korean_name}</h1>
    <Link href="/" className="bg-blue-500 text-white py-2 px-4 rounded-full hover:bg-blue-700">뒤로가기</Link>
  </div>
  <Image src={pokemonData.sprites.front_default} alt={pokemonData.korean_name} width={128} height={128} className="w-32 h-32 mx-auto mb-4" />
</div>
  • 포켓몬의 이름과 이미지를 표시하며, "뒤로가기" 버튼을 제공.

6. 타입 및 능력 정보

<div className="flex flex-wrap gap-3 mb-4">
  <h2 className="text-xl font-semibold">타입:</h2>
  <ul className="flex flex-wrap gap-2">
    {pokemonData.types.map((typeInfo: any) => (
      <li key={typeInfo.type.name} className="text-lg px-2 py-1 rounded-full text-white" style={{ backgroundColor: typeColors[typeInfo.type.name] }}>
        {typeInfo.type.korean_name}
      </li>
    ))}
  </ul>
  ...
</div>
  • 포켓몬의 타입을 색상과 함께 표시. 타입별로 다른 배경색을 적용.

7. 신장 및 체중

<div className="mb-4">
  <h2 className="text-xl font-semibold">신장 및 체중:</h2>
  <ul className="flex flex-wrap gap-2">
    <li className="text-lg">신장: {pokemonData.height} cm</li>
    <li className="text-lg">체중: {pokemonData.weight} g</li>
  </ul>
</div>
  • 포켓몬의 신장과 체중 정보를 표시.

8. 능력치

<div className="mb-4">
  <h2 className="text-xl font-semibold">능력치:</h2>
  <ul>
    {pokemonData.stats.map((statInfo: any) => (
      <li key={statInfo.stat.name} className="text-lg mb-2">
        {statInfo.stat.name}: <span className="ml-2">{statInfo.base_stat}</span>
        <div className="relative w-full h-4 bg-gray-200 rounded-full overflow-hidden">
          <div className="absolute top-0 left-0 h-full bg-blue-500" style={{ width: `${(statInfo.base_stat / 255) * 100}%` }}></div>
        </div>
      </li>
    ))}
  </ul>
</div>
  • 포켓몬의 각 능력치를 시각적으로 표현. 능력치 값을 기반으로 진행 바를 표시.

🐛문제: next/image 사용 시 이미지 로드 문제

next/image 컴포넌트를 사용하여 외부 URL에서 이미지를 로드하려고 할 때, 이미지가 제대로 로드되지 않는 문제가 발생했습니다. 이는 Next.js의 이미지 최적화 기능이 외부 URL을 처리하기 위해 추가적인 설정을 필요로 하기 때문입니다.

해결 방법: next.config.js 설정 추가

이 문제를 해결하기 위해 next.config.js 파일에 다음과 같은 설정을 추가했습니다:

module.exports = {
  images: {
    remotePatterns: [
      {
        protocol: "https",
        hostname: "raw.githubusercontent.com",
      },
    ],
  },
};

배운 점

  • Next.js의 동적 라우팅과 비동기 데이터 페칭을 통해 API 데이터를 효과적으로 가져오는 방법
  • React 컴포넌트를 사용하여 데이터를 시각적으로 표현하는 방법
  • 타입스크립트를 사용하여 코드의 안정성을 높이는 방법
  • Tailwind CSS를 사용하여 빠르게 스타일을 적용하는 방법
profile
블로그 관리 하루에 한번씩 도전!

0개의 댓글