[TIL #46] Next.js 개인과제 트러블슈팅

차슈·2024년 7월 3일
0

TIL

목록 보기
47/70
post-thumbnail

문제

같은 코드로 다른 분들 컴퓨터에서는 잘 돌아가는데, 내 로컬에서는 로또로결과가 나왔다. 이게 그 말로만 듣던 로또로 결과값 나오기,,,,

확인해보니 데이터가 들어왔다가 다시 초기화가 되는것 같다. 왜 그런건지는 모르겠어서 해결하는데에 많은 시간이 들었다. 왜냐? 나한테만 나는 에러니까,,

라우터는 주어진 부분이라 모두가 다 같고, 그럼 내가 짠 코드에서 에러가 나는건데, map 에러가 내 컴퓨터에서만 나고 다른 분들 컴퓨터에서는 괜찮은거 보면 코드의 문제가 아니라고 생각했다.

심지어 npm run dev랑 build start 했을 때 차이가 있어서 더 의아했다.

"use client";
import Image from "next/image";
import React, { useEffect, useState } from "react";

type Pokemon = {
  id: number;
  name: string;
  korean_name: string;
  height: number;
  weight: number;
  sprites: { front_default: string };
  types: { type: { name: string; korean_name: string } }[];
  abilities: { ability: { name: string; korean_name: string } }[];
  moves: { move: { name: string; korean_name: string } }[];
};

const page: React.FC = () => {
  const [pokemons, setPokemons] = useState<Pokemon[]>([]);
  const [loading, setLoading] = useState<boolean>(true);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    const fetchPokemons = async () => {
      try {
        const response = await fetch("/api/pokemons");
        if (!response.ok) {
          throw new Error("불러오기 에러 ");
        }
        const data: Pokemon[] = await response.json();
        setPokemons(data);
      } catch (error) {
        setError("데이터 에러 ");
      } finally {
        setLoading(false);
      }
    };

    fetchPokemons();
  }, []);

  if (loading) {
    return <div className="text-center">Loading...</div>;
  }

  if (error) {
    return <div className="text-center">{error}</div>;
  }

  return (
    <div>
      <h1 className="text-center text-2xl font-bold my-4"> 포켓몬 도감 </h1>
      <ul className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-4 m-4">
        {pokemons.map((pokemon) => (
          <li
            key={pokemon.id}
            className="bg-black p-4 rounded-lg text-center text-white cursor-pointer"
          >
            <Image
              src={pokemon.sprites.front_default}
              alt={pokemon.name}
              width={96}
              height={96}
              className="mb-2 mx-auto"
            />
            <div className="font-bold">{pokemon.korean_name}</div>
            <div className="text-sm">{pokemon.name}</div>
          </li>
        ))}
      </ul>
    </div>
  );
};

export default page;

해결방법

1. 캐시삭제

1 // 캐시 제거
rm -rf .next
2 // 의존성 재설치
rm -rf node_modules
npm cache clean --force
npm install
3 // 포트 다른 거 시도
npm run dev -- -p 3001

이렇게도 해보고, VSCODE도 나가보고 했지만, 여전히 결과는 달라지지 않았다.

2. 구조분해할당

setpokemons에 구조분해 할당을 해도 결과는 달라지지 않았다.

3. 라우터 수정

route에서 PromiseAll 때문에 데이터가 초기화가 되고 있다. 이거 때문인건가 하고, error catch 부분에서

 return null; // 실패한 요청은 null을 반환
// return throw;

return throwreturn null 로 바꿔주었더니 해결되었다.
사실 아직도 정확한 이유는 잘 모르겠다. 코드의 이상이 있는것도, route는 다 공통적으로 쓰는데 내 로컬만 문제가 생긴것도 잘 모르겠다.
더 정확한 이유를 알면 추가하도록 하겠다.

진짜 말로만 듣던 로또로 결과값 나오기 제일 빡센 에러고치기였다. 한 3시간 걸린거같은데 결국엔 다시 처음으로 돌아가서 해결했다.

잘 안될때 처음으로 돌아가서 다시 보는것도 하나의 해결방법인 것 같다.
같이 찾아준 종하님께 감사인사를 전한다.

route 전체 코드

import axios from "axios";
import { NextResponse } from "next/server";

const TOTAL_POKEMON = 151;

export const GET = async (request: Request) => {
  try {
    const allPokemonPromises = Array.from(
      { length: TOTAL_POKEMON },
      async (_, index) => {
        const id = index + 1;
        try {
          const [response, speciesResponse] = await Promise.all([
            axios.get(`https://pokeapi.co/api/v2/pokemon/${id}`),
            axios.get(`https://pokeapi.co/api/v2/pokemon-species/${id}`),
          ]);

          const koreanName = speciesResponse.data.names.find(
            (name: any) => name.language.name === "ko"
          );

          return {
            ...response.data,
            korean_name: koreanName?.name || null,
          };
        } catch (error) {
          console.error(`Failed to fetch data for Pokemon #${id}:`, error);
          return null; // 실패한 요청은 null을 반환
          // return throw;
        }
      }
    );

    const allPokemonData = (await Promise.all(allPokemonPromises)).filter(
      Boolean
    );

    return NextResponse.json(allPokemonData);
  } catch (error) {
    console.error("Failed to fetch data:", error);
    return NextResponse.json(
      { error: "Failed to fetch data" },
      { status: 500 }
    );
  }
};

된 줄 알았는데 아니였음... 내 환경에선 안되고 종하님 환경에선 되어서 소거법으로 하나씩 비교하다가 node js의 버전의 차이를 발견했다.

next js가 node js에서 동작하는 프레임 워크라서 node js 업그레이드 했더니 해결 완료,,.,,

이틀 걸렸다 와

brew upgrade node

나는 이 명령어 썼다!

0개의 댓글