반려동물 목록의 이미지와 이름이 표시되지 않는 오류 해결

2025. 2. 27. 01:45프론트엔드

 

상황

프론트 뷰에서 반려동물 관리를 누르면 내가 등록한 반려동물 목록이 출력된다.

그런데 목록에 반려동물의 이미지와 이름이 떠야하는데 뜨지 않았다.

생성되는 목록 갯수를 보면 잘 출력이 되고, 백엔드에서도 확인해본 결과 결과는 잘 내려와졌다.

뭐가 문제인지 하나하나 찾아보기로 했다!

 

  • 현재 코드
import { useEffect, useState } from "react";
import { Link } from "react-router-dom";
import { getPetsById } from "../api/auth";
import basicPicture from "../assets/basicPicture.png";

interface Pet {
  id: number;
  name: string;
  image: string | null;
}

const PetManagement = () => {
  const [pets, setPets] = useState<Pet[]>([]);
  const [loading, setLoading] = useState<boolean>(true);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    const getPets = async () => {
      try {
        const response = await getPetsById();
        console.log("response : " + response);
        setPets(response);
        setLoading(false);
      } catch (error) {
        console.error("등록 실패 : " + error);
        setError("❌ 데이터를 불러오는 중 오류가 발생했습니다. ❌");
        setLoading(false);
      }
    };

    getPets();
  }, []);

  return (
    <div className="relative px-40 pt-16 min-h-screen">
      <h1 className="text-3xl font-bold mb-14">반려동물 하우스 🏠</h1>
      <Link
        to="/createPetInfo"
        className="absolute right-72 top-20 bg-blue-400 rounded-full w-24 h-10 text-white font-semibold shadow-md flex items-center justify-center"
      >
        추가하기
      </Link>

      {loading && <p className="text-center text-3xl">로딩 중..</p>}

      {error && <p className="text-center text-3xl text-red-500">{error}</p>}

      {!loading && !error && pets.length === 0 && (
        <p className="text-center text-3xl">등록된 반려동물이 없습니다.</p>
      )}

      {!loading && !error && (
        <div className="grid grid-cols-3 gap-6">
          {pets.map((pet) => (
            <div key={pet.id} className="text-center">
              <img
                src={image || basicPicture}
                alt={name}
                className="w-60 mx-auto mb-4"
              />
              <h2 className="text-xl font-semibold">{name}</h2>
            </div>
          ))}
        </div>
      )}
    </div>
  );
};

export default PetManagement;

 

과정 & 해결

1. S3 버켓 이미지 조회 권한 정책 수정 - 이미지 표시 성공 ✅

AWS의 이미지에 이상이 있을 수 있어 확인해보았다. 원래 객체 URL를 클릭하면 이미지가 나와야하는데 나오지 않았다.

권한에 문제가 있는 것 같아 S3 정책을 설정해주었다.

 

S3 > 버킷 > 설정할 버킷 선택 > 권한 탭 선택 > 버킷 정책의 편집 버튼 선택

 

정책 생성기 선택

 

위와 같이 입력해준 후 Add Statement를 선택 > Generate Policy 선택

 

조금 설명을 해보자면 Principal 은 어떤 사용자에게 권한을 줄것인지 설정하는데 나는 *을 사용하여 모든 사용자에게 권한을 주었다.

Actions는 어떤 권한을 줄건지 나는 GetObject를 선택했다.

ARN은 바로 위 버킷 정책 편집 이미지의 버킷 ARN

/*

을 입력하면 된다. 반드시 마지막에 /*을 붙여줘야 한다!

 

 

생성된 정책을 다시 AWS 정책에 붙여넣고 저장을 한다.

 

그럼 이제 아까 에러가 났던 S3 > 객체 URL을 선택 시 이미지가 잘 뜬다!

 

2. 응답 데이터의 변수명과 interface의 변수명 일치 시키기 - 이름 표시 성공 ✅

백엔드에서 내려오고 있는 응답을 출력해본 결과 아래 처럼 나오고 있었다.

 

그런데 내가 interface로 만들어서 받고 있는 Pet객체의 변수명이 달랐던 것이다.

petName으로 응답이 내려오니 내 Pet 인터페이스의 변수명인 name과 달라 매핑되지 않았고, 값이 들어가지 않았던 것

아래 처럼 코드를 고쳐주었더니 이름이 잘 받아서 표시되었다.

interface Pet {
  petId: number;
  petName: string;
  petImg: string | null;
}

    {!loading && !error && (
    <div className="grid grid-cols-3 gap-6">
      {pets.map((pet) => (
        <div key={pet.petId} className="text-center">
          <img
            src={pet.petImg || basicPicture}
            alt={pet.petName}
            className="w-60 mx-auto mb-4"
          />
          <h2 className="text-xl font-semibold">{pet.petName}</h2>
        </div>
      ))}
    </div>
    )}

 

 

이번 에러도 멋지게 해냈다!

나는야 멋장이