React JS로 영화 웹 서비스 만들기

강서현·2022년 8월 21일
0


영화 소개 메인페이지와 디테일 페이지를 완성하는 코드이다. 결과 화면은 위와 같다.

각각의 파일을 하나씩 설명하겠다.

App.js

위의 두 페이지를 연결하는 코드이다. 다만 강의에 나온 Switch를 리액트가 더이상 지원하지 않게 되면서, 대신 Routes를 사용했다.많은 변화가 필요하지 않다.

import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
//각 화면 불러오기
import Detail from "./routes/Detail";
import Home from "./routes/Home";
function App() {
  return (
    <Router>
      <Routes>
        <Route path="/movie/:id" element={<Detail/>} /> 
		//디테일. 동적으로 해당하는 id의 페이지를 보여준다. Detail.js 참조
        <Route path="/" element={<Home/>} /> //메인
      </Routes>
    </Router>
  );
}

export default App;

이 방식이 싫으면 npm i react-router-dom@5.3.0 커맨드를 사용하면 (아마) Switch도 될 것이다.

Home.js

다음은 메인화면이다. 영화 정보를 불러오고, 컴포넌트에 필요한 props를 전달하는 것을 포함한다.

import { useEffect, useState } from "react";
import Movie from "../components/Movie";
import styles from "./Home.module.css";

function Home() {
  const [loading, setLoading] = useState(true);
  //로딩창 설정
  const [movies, setMovies] = useState([]);
  const getMovies = async () => {
    const json = await (
      await fetch(
        `https://yts.mx/api/v2/list_movies.json?minimum_rating=8.8&sort_by=year`
      )
    ).json(); 
    
    setMovies(json.data.movies);
    setLoading(false);
    //로딩중을 풀어준다.
  };
  //응답을 받아와 json 파일에 저장한다. 평점 8.8 이상만 저장한 것을 알 수 있다.
  useEffect(() => {
    getMovies();
  }, []);
  return (
    <div className={styles.container}>
      {loading ? (
       //로딩중이 아니라면 영화들을 보여줄 것이다.
        <div className={styles.loader}>
          <span>Loading...</span>
        </div>
      ) : (
        <div className={styles.movies}>
          {movies.map((movie) => (
            //mpp을 사용해 배열을 변형/여기서 배열은 Movie 컴포넌트
            <Movie
              key={movie.id}
          	//고유한 값인 id 사용. props로 정보를 보낸다.
              id={movie.id}
              year={movie.year}
              coverImg={movie.medium_cover_image}
              title={movie.title}
              summary={movie.summary}
              genres={movie.genres}
			//상영연도, 이미지, 제목, 요약, 장르를 가져왔다.
            />
          ))}
        </div>
      )}
    </div>
  );
}
export default Home;

Movie.js

이제 받아온 값을 기반으로 각 영화를 컴포넌트로 작성한다.

import PropTypes from "prop-types";
import { Link } from "react-router-dom";
import styles from "./Movie.module.css";

function Movie({ id, coverImg, title, year, summary, genres }) {
  //받아온 props들은 전부 가져온다.
  return (
    <div className={styles.movie}>
      <img src={coverImg} alt={title} className={styles.movie__img} />
        //포스터
      <div>
        <h2 className={styles.movie__title}>
          <Link to={`/movie/${id}`}>{title}</Link>
		//제목. 그런데 Detail 페이지로 가는 링크가 걸려있다.
        </h2>
        <h3 className={styles.movie__year}>{year}</h3>
        <p>{summary.length > 235 ? `${summary.slice(0, 235)}...` : summary}</p>
		//요약은 너무 길지 않도록 235자에서 끊고 ...으로 축약한다.
        <ul className={styles.movie__genres}>
          {genres.map((g) => (
            <li key={g}>{g}</li>
          ))}
        </ul>
      </div>
    </div>
  );
}

Movie.propTypes = {
//propTypes를 보기 위한 코드이다.
  id: PropTypes.number.isRequired,
  coverImg: PropTypes.string.isRequired,
  title: PropTypes.string.isRequired,
  summary: PropTypes.string.isRequired,
  genres: PropTypes.arrayOf(PropTypes.string).isRequired,
};

export default Movie;

Detail.js

영화의 상세설명을 보여주는 파일이다. 원하는 방식으로 구성하면 된다.

import { useEffect } from "react";
import { useParams } from "react-router-dom";
function Detail() {
 const { id } = useParams();
 const getMovie = async () => {
   const json = await (
     await fetch(`https://yts.mx/api/v2/movie_details.json?movie_id=${id}`)
   ).json();
   console.log(json);
 };
 //props 값에 해당하는 상세설명을 가져온다.
 useEffect(() => {
   getMovie();
 }, []);
 return <h1>Detail</h1>;
}
export default Detail;

여기에 적절한 css 파일을 더하게 되면 위의 웹사이트가 나온다.

0개의 댓글