코리아 IT아카데미/react.js

9일차 | API로 영화 소개 페이지 제작

Sharon kim 2022. 3. 23. 12:03

 

yts.mx/api#list_movies
https://yts-proxy.now.sh/list_movies.json

yarn add axios

App.js

import React from "react";
import axios from "axios";
import Movie from "./movies";
import "./App.css";

class App extends React.Component {
  state = {
    isLoading: true,

    movies: [],
  };

  getMovies = async () => {
    //async는 이 함수가 비동기식을 의미

    const {
      data: {
        data: {movies},
      },
    } = await axios.get(
      "https://yts-proxy.now.sh/list_movies.json?sort_by=rating"
    );

    //console.log(movies);

    //console.log(movies.data.data.movies);

    this.setState({movies, isLoading: false});
  }; //await 대기중

  componentDidMount() {
    this.getMovies();
  }

  render() {
    const {movies, isLoading} = this.state;

    return (
      <div className="container">
        {/* {isLoading ? '로딩' : '대기'}  */}

        <div className="movies">
          {isLoading
            ? "로딩"
            : movies.map((movie) => (
                //console.log(movie)

                <Movie
                  id={movie.id}
                  year={movie.year}
                  title={movie.title}
                  summary={movie.summary}
                  poster={movie.medium_cover_image}
                />
              ))}
        </div>
      </div>
    );
  }
}

export default App;
yarn add prop-types

Movie.js

import React from "react";
import PropTypes from 'prop-types';
import './movies.css';
//yarn add prop-types

function Movie({id, year, title, summary, poster}) { 
    return (
      <div className="movie">
        <img src={poster} alt={title} />
        <h5 className="movie__title">{title}</h5>
        <h5 className="movie__year">{year}</h5>
        <h5 className="movie__summary">{summary}</h5>
      </div>
    );
}

Movie.PropTypes = { //타입 검사
    id: PropTypes.number.isRequired,
    year: PropTypes.number.isRequired,
    title: PropTypes.number.isRequired,
    summary: PropTypes.number.isRequired,
    poster: PropTypes.number.isRequired
};

export default Movie;

 

App.css

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  padding: 0;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen,
    Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
  background-color: #f7f5f5;
  height: 100%;
}
  
html,
body,
#zzz,
.container {
  height: 100%;
  display: flex;
  justify-content: center;
}

.loader {
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}

.movies {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  flex-wrap: wrap;
  padding: 50px;
  padding-top: 70px;
  width: 80%;
}

 

Movie.css

.movies .movie {
    width: 45%;
    background-color: white;
    margin-bottom: 70px;
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    font-weight: 300;
    padding: 20px;
    border-radius: 5px;
    color: #b2b3bc;
    box-shadow: 0 13px 27px -5px rgba(50, 50, 93, 0.25),
      0 8px 16px -8px rgba(0, 0, 0, 0.3), 0 -6px 16px -6px rgba(0, 0, 0, 0.025);
  }
  
  .movie img {
    position: relative;
    top: -50px;
    max-width: 150px;
    width: 100%;
    margin-right: 30px;
    box-shadow: 0 30px 60px -12px rgba(50, 50, 93, 0.25),
      0 8px 36px -18px rgba(0, 0, 0, 0.3), 0 -12px 36px -8px rgba(0, 0, 0, 0.025);
  }
  
  .movie .movie__year,
  .movie .movie__title {
    margin: 0;
    font-weight: 300;
  }
  
  .movie .movie__title {
    margin-bottom: 5px;
    font-size: 24px;
    color: #2c2c2c;
  }
  
  .movie .movie__genres {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    margin: 5px 0px;
  }
  .movie .movie__year {
    margin-right: 10px;
    font-size: 14px;
  }

 

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './App.css';
import App from './App';


ReactDOM.render(
  
    <App />,

  document.getElementById('root')
);