🚀 프로젝트/집플래닛

집플래닛 트러블 슈팅 | 리뷰 삭제 버튼 로직 처리 문제

seheej 2024. 10. 18. 19:24

문제 상황

ReviewsDisplay 컴포넌트에서 리뷰 목록을 보여줄 때 ReviewCard를 사용하지만, 삭제 버튼이 필요하지 않은 상황입니다. 그래서 showActions prop을 사용하여 삭제 및 수정 버튼을 조건부로 숨기도록 했습니다. 하지만 ReviewCard 컴포넌트에서 onDelete 함수는 여전히 필수적으로 전달되도록 되어 있기 때문에, ReviewsDisplay에서 삭제 로직을 구현하지 않은 상태에서 onDelete 함수를 넘겨주지 않으면 오류가 발생하는 상황이었습니다.

문제 원인

ReviewCard 컴포넌트는 onDelete 함수가 필수로 제공된다고 가정하고 있고, ReviewsDisplay에서 showActions={false}로 설정했음에도 불구하고 onDelete 함수를 전달하지 않으면 TypeScript는 이 함수가 누락되었다고 판단하여 에러를 발생시킵니다.

해결 방법

onDelete 함수를 선택적인 prop으로 변경하여, showActions가 true일 때만 해당 함수가 사용되도록 하였습니다. 즉, onDelete를 필수 prop에서 선택적 prop으로 수정하고, showActions가 true일 때만 해당 함수가 호출되도록 수정합니다.

 

수정된 코드 및 설명

1. ReviewCard에서 onDelete를 선택적 prop으로 설정

interface ReviewCardProps {
  review: Review; // 개별 리뷰 객체
  onDelete?: (articleId: number) => void; // 삭제 함수 - 선택적
  showActions?: boolean; // 수정/삭제 버튼 표시 여부
}

const ReviewCard: React.FC<ReviewCardProps> = ({ review, onDelete, showActions = false }) => {
  const router = useRouter();

  const handleEdit = () => {
    router.push(`/review/${review.article_id}/modify`);
  };

  const handleDelete = async (article_id: number) => {
    if (onDelete) {
      await deleteUserReview(article_id);
      onDelete(article_id);
    }
  };

  return (
    <div onClick={() => router.push(`/review/${review.article_id}`)} className="cursor-pointer">
      <li className="p-4 border rounded-lg shadow flex flex-col hover:shadow-lg transition-shadow duration-200">
        <div className="flex items-center">
          <h2 className="text-lg font-semibold mr-2">
            {review.house_name || review.address || "주소 정보 없음"}
          </h2>
          <span className="text-lg mr-2">⭐️{scoreAverage(review)}</span>

          {showActions && (
            <div className="flex items-center ml-auto">
              <button
                onClick={(e) => {
                  e.stopPropagation();
                  handleEdit();
                }}
                className="ml-2 text-blue-600"
              >
                수정
              </button>
              <button
                onClick={(e) => {
                  e.stopPropagation();
                  handleDelete(review.article_id);
                }}
                className="ml-2 text-red-600"
              >
                삭제
              </button>
            </div>
          )}
        </div>
        <hr className="my-2 border-gray-300" />
        <div className="flex">
          <div className="w-1/2 p-1">
            <span className="good-label">장점</span>
            <p className="text-gray-700 mt-2 text-[11px] line-clamp-2">{review.good}</p>
          </div>
          <div className="border-l border-gray-300 mx-2"></div>
          <div className="w-1/2 p-1">
            <span className="bad-label">단점</span>
            <p className="text-gray-700 mt-2 text-[11px] line-clamp-2">{review.bad}</p>
          </div>
        </div>
      </li>
    </div>
  );
};

2. ReviewsDisplay에서 onDelete 함수 제거

const ReviewsDisplay: React.FC<ReviewsDisplayProps> = ({ sortOrder }) => {
  const [reviews, setReviews] = useState<Review[]>([]);
  const [loading, setLoading] = useState<boolean>(true);

  useEffect(() => {
    const fetchReviews = async () => {
      setLoading(true);
      const fetchedReviews = await getAllReviews(); // 모든 리뷰 가져오기
      setReviews(fetchedReviews);
      setLoading(false);
    };
    fetchReviews();
  }, []);

  const displayedReviews = sortedReviews(); // 정렬된 리뷰를 변수에 저장

  if (loading) {
    return <p>리뷰를 불러오는 중...</p>;
  }

  return (
    <div>
      <h1 className="text-xl font-bold mb-4">리뷰 목록</h1>
      <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
        {displayedReviews.length > 0 ? (
          displayedReviews.map((review) => (
            <ReviewCard key={review.article_id} review={review} showActions={false} /> // 삭제 버튼 표시하지 않음
          ))
        ) : (
          <p>작성한 후기가 없습니다.</p>
        )}
      </div>
    </div>
  );
};

 

트러블 슈팅 요약

  • 문제: ReviewCard에서 삭제 버튼이 필요 없는 경우에도 onDelete 함수가 전달되지 않으면 에러가 발생.
  • 원인: onDelete가 필수 prop으로 설정되어 있었음.
  • 해결: onDelete를 선택적 prop으로 변경하고, showActions가 true일 때만 해당 함수가 호출되도록 수정.

이 방식으로 불필요한 삭제 로직을 제거하고, ReviewsDisplay에서 삭제 버튼이 필요 없는 경우에도 오류 없이 동작하도록 했습니다.