본문 바로가기
SeSAC

[코딩온] TMDB API에서 genre name 대신 genreID만 나올 때

by 새파란레몬 2023. 12. 24.
import React, { useState, useEffect } from 'react';
import { Link, useNavigate } from 'react-router-dom';
import axios from 'axios';
import Loading from '../Loading';

export default function MovieResult({ query }) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);
  //전체 장르 코드 매핑
  const genreMapping = {
    28: 'Action',
    12: 'Adventure',
    16: 'Animation',
    35: 'Comedy',
    80: 'Crime',
    99: 'Documentary',
    18: 'Drama',
    10751: 'Family',
    14: 'Fantasy',
    36: 'History',
    27: 'Horror',
    10402: 'Music',
    9648: 'Mystery',
    10749: 'Romance',
    878: 'Science Fiction',
    10770: 'TV Movie',
    53: 'Thriller',
    10752: 'War',
    37: 'Western',
  };
  
  //장르 이름 find 함수
  const getGenreNames = (genreIds) => {
    return genreIds
      .map((id) => genreMapping[id])
      .filter((name) => name)
      .join(' ');
  };

  useEffect(() => {
    if (!query) {
      setLoading(false); // Stop loading if there is no query
      return;
    }
    const fetchData = async () => {
      //query가 없다면 return
      if (!query) return;
      try {
        const response = await axios.get(
          `https://api.themoviedb.org/3/search/movie?query=${encodeURIComponent(
            query
          )}&include_adult=false&language=en-US&page=1`,
          {
            headers: {
              accept: 'application/json',
              Authorization: `Bearer ${process.env.REACT_APP_TMDB_KEY}`,
            },
          }
        );
        const filteredMovies = response.data.results.filter((movie) => {
          const releaseYear = new Date(movie.release_date).getFullYear();
          return releaseYear >= 1927 && releaseYear <= 1969;
        });

        setData({ ...response.data, results: filteredMovies });
      } catch (error) {
        setError(error);
      } finally {
        setLoading(false);
      }
    };

    fetchData();
  }, [query]);

  const renderContent = () => {
    if (loading) return <Loading />;

    if (!query || (data && data.results.length === 0)) {
      return (
        <div className="title-no-result">
          <div>No results found.</div>
          <div>
            Please try a different search term to discover something new.
          </div>
        </div>
      );
    }

    return data.results.map((movie, index) => (
      <div className="one-movie-div" key={index}>
        {/* <p>Title: {movie.original_title}</p> */}
        <div className="img-wrapper image-hover-effect">
          <Link to={`/films/detail/${movie.id}`}>
            <img
              src={`https://image.tmdb.org/t/p/original${
                movie.backdrop_path || movie.poster_path
              }`}
              alt={movie.name}
            />
          </Link>
        </div>
        <div>
          <div className="date-div">{formatDate(movie.release_date)}</div>

          <Link to={`/films/detail/${movie.id}`}>
            <div className="title-content">{movie.original_title}</div>
          </Link>
          <div className="movie-search-data">
            <div className="search-detail-title">Genre</div>
            // 장르 이름 함수 활용 코드
            <div>{getGenreNames(movie.genre_ids)}</div>
          </div>
          <div className="movie-search-data">
            <div className="search-detail-title">Plot</div>
            <div style={{ textAlign: 'justify' }}>{movie.overview}</div>
          </div>
          <div className="movie-btn-flex">
            <Link to={`/films/detail/${movie.id}`}>
              <button>Details</button>
            </Link>
          </div>
        </div>
      </div>
    ));
  };

  return <div>{renderContent()}</div>;
}

 

위가 내가 기획했던 페이지였다. 보면 장르에 drama war romance등으로 표시되야 하는데 이전 글에서도 말했듯이 이 TMDB API는 장르 정보를 id number로만 주었다.

 

아쉽게도 위의 한번의 요청으로는 genre_id 숫자만 나올뿐 이름이 나오지는 않았다.

 

genre의 전체 데이터가 생각보다 단순하길래 아예 object 형태로 만들어 버리고

→ const genreMapping

장르 데이터를 얻을 수 있는 주소 : ( https://developer.themoviedb.org/reference/genre-movie-list )

 

date를 처리했던 방식과 같이 filter 하는 함수 getGenreNames() 를 정의해주어  한 번 거친 후 data가 보여지도록 처리해주었다.


useEffect를 한 번 더 쓰면 request 결과를 따로 받아올 수 있지만, 위와 같은 간단한 데이터는 그냥 한 파일에 담아 탐색하는 함수를 써주는 것이 더 간편할 것 같아 위와 같은 코드를 작성하게 되었다.