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 결과를 따로 받아올 수 있지만, 위와 같은 간단한 데이터는 그냥 한 파일에 담아 탐색하는 함수를 써주는 것이 더 간편할 것 같아 위와 같은 코드를 작성하게 되었다.
'SeSAC' 카테고리의 다른 글
코딩온 비전공자, 입문자도 가능한 웹 개발자 부트캠프 후기 (4) | 2024.01.18 |
---|---|
[코딩온] SeSAC 세번째 프로젝트 회고록 (0) | 2024.01.06 |
[코딩온]Image grid 형태로 Infinite scroll 기능 구현하기 (0) | 2024.01.03 |
[코딩온] 검색 기능 구현을 위한 TMDB API의 활용 방법 (0) | 2023.12.21 |
[코딩온] 프론트 혼자 로그인 구현 과정 recoil-persist (feat. 실패) (0) | 2023.12.17 |