React와 React-router-dom 그리고 비동기 통신을 사용하여 영화 리스트 앱을 만들어보세요.
과제에 들어가기 전에 React-router-dom에 대해 간단히 알고 넘거가는게 좋을 것 같다.
일반적으로 HTML, CSS, JS로 작성된 웹 사이트와 다르게 작동한다.
먼저 React는 가상 DOM으로 구현되어 있으며 필요한 부분만 그때그때 DOM을 다시 그리고 만든다.
또 모든 내용이 자바스크립트로만 구현 되어있기 때문에 페이지를 이동하면 모든 페이지를 새로 받아야하는 일반적인 웹 사이트와는 다르게 필요한 부분만 교체할 수 있다.
React-router-dom은 그런 React의 페이지 이동을 편하게 해주는 라이브러리다.
React-router-dom을 사용하는 큰 이유는 React의 가장 큰 장점인 상태관리를 그대로 이어서 할 수 있다는 장점을 가지고 있다.
기본적인 a태그를 사용해서 하는 경우 모든 상태가 날아가기 때문에 리액트에선 치명적으로 작동할 수 있다.
아예 외부 태그로 나가는 경우라면 상관은 없다.
//Home.jsx
import { useEffect, useState } from "react";
import styles from "../styles/Home.module.css";
import MovieList from "../components/MovieList";
const Home = () => {
const [movies, setMovies] = useState();
const dataFetch = async () => {
await fetch(
`https://yts.mx/api/v2/list_movies.json?minimum_rating=8.8&sort_by=year`
)
.then((response) => response.json())
.then((response) => {
setMovies(response.data);
});
};
useEffect(() => {
dataFetch();
}, []);
return (
<div className={styles}>
<MovieList data={movies} />
</div>
);
};
export default Home;
가장 먼저 화면에 출력되는 홈 화면이다.
이곳에서 영화 리스트를 받고 자식 컴포넌트에 데이터들을 넘겨준다.
//
import styles from "../styles/MovieList.module.css";
import { useNavigate } from "react-router-dom";
const MovieList = (props) => {
console.log(props.data);
const navigate = useNavigate();
return (
<div className={styles.movieList}>
<div className={styles.totalMovieCount}>
{props.data && props.data.movie_count}개의 영화
</div>
<ul>
{props.data &&
props.data.movies.map((e) => (
<li key={e.id}>
<button
onClick={() => {
navigate("/movie", {
state: { ...e },
});
}}
>
<img src={e.medium_cover_image} alt="영화 썸네일" />
<div className={styles.movieInfo}>
<h3 className={styles.singleLine}>
{e.title} ({e.title_english})
</h3>
<div className={styles.score}>
<p>평점 {e.rating}</p>
<p className="year">({e.year})</p>
</div>
<p className={styles.genres}>
{Object.keys(e.genres).map((elements, i) => (
<div key={i}>{e.genres[elements]}</div>
))}
</p>
</div>
</button>
</li>
))}
</ul>
</div>
);
};
export default MovieList;
무비 리스트에선 받은 데이터들을 map을 사용하여 화면에 리스트로 출력해준다.
이곳에서 원하는 목록 중 하나 선택하여 상세페이지로 이동하도록 한다.
목록을 받아올때 상세페이지에 필요한 정보들이 다 들어있기 때문에 navigate를 사용하고 state에 집어넣어서 이동 했을 때도 계속 활용할 수 있도록 하였다.
import { useLocation } from "react-router-dom";
import styles from "../styles/MovieDetail.module.css";
import StarRating from "../components/StarRating";
const MovieDetail = () => {
const data = useLocation().state;
console.log(data);
return (
<div className={styles.detailContentWrapper}>
<div className={styles.backgroundOverlay}>
<div className={styles.backgroundImage}>
<img
className={styles.background}
src={data.background_image_original}
alt="배경화면 이미지"
></img>
</div>
</div>
<div className={styles.contentWrapper}>
<img
src={data.large_cover_image}
alt="영화 포스터"
className={styles.images}
></img>
<div className={styles.detailInfo}>
<h2>
제목: {data.title_long} {data.title_english}
</h2>
<div className={`${styles.severalLines} ${styles.moviePlot}`}>줄거리: {data.description_full}</div>
<div className={styles.ratingScore}>
평점: <StarRating rating={data.rating} />
</div>
<div>언어: {data.language}</div>
<div>
장르{" "}
{Object.keys(data.genres).map((elements, i) => (
<span key={i}>{data.genres[elements]} </span>
))}
</div>
<a
href={`https://search.naver.com/search.naver?where=nexearch&sm=top_hty&fbm=0&ie=utf8&query=${data.title}`}
>
네이버에 이 영화 검색하러 가기
</a>
</div>
</div>
</div>
);
};
export default MovieDetail;
영화 상세보기 페이지에서는 방금 이동하기 전에 받아온 데이터들을 가지고 화면에 출력하도록 하였으며 추가적으로 네이버에 영화에 대한 것들을 검색할 수 있도록 하였다.
이번 과제는 리액트로 간단하게 router를 사용하여 페이지 전환하고 api 통신을 하는 정도로 끝냈다.
간단하지만 나름대로 리액트의 핵심이 담긴 프로젝트 아니었을까 싶다.
본 후기는 유데미-스나이퍼팩토리 10주 완성 프로젝트캠프 학습 일지 후기로 작성 되었습니다.
#프로젝트캠프 #프로젝트캠프후기 #유데미 #스나이퍼팩토리 #웅진씽크빅 #인사이드아웃 #IT개발캠프 #개발자부트캠프 #리액트 #react #부트캠프 #리액트캠프