본문 바로가기

Archived(Programming)/ReactJS

ReactJS_8_MovieApp_보충

1. Data 받아오기

json 요청으로 가져온 데이터 중에서,

필요한 데이터 컬럼을 log를 통해 찍어서 확인한 뒤 그에 맞게 가져온다.

가져올 때는 최대한 Component 단위로 쪼개서 가져오는 것이 세련된 코드이다.

/src/App.js

import React, { Component } from 'react';
import './App.css';
import Movie from './Movie.js';

class App extends Component {

  state = {
  }

  componentDidMount(){
    this._getMovies()
  }

  _getMovies = async() => {
    const movies = await this._callApi()
    this.setState({
      movies
    })
  }

  _callApi = () => {
    return fetch("https://yts.lt/api/v2/list_movies.json?sort_by=download_count")
      .then(potato => potato.json()) //console찍어보자
      .then(json => json.data.movies) //console찍어보자
      .catch(err => console.log(err))
  }

_renderMovies = () => {
  const movies = this.state.movies.map((movie) => {
    console.log(movie) 
    //log을 통해 Movie 객체 내용확인
    return <Movie 
      title={movie.title_english} 
      poster={movie.medium_cover_image} 
      key={movie.id} 
      genres={movie.genres}
      synopsis={movie.synopsis}
    /> //key값을 id값으로 부여
  })
  return movies
}

  render() {
    const { movies } = this.state;
    return (
      <div className={movies ? "App" : "App--loading"}>
        {movies ? this._renderMovies() : "Loading"}
      </div>
    );
  }
}
export default App;

/src/Movie.js

import React from 'react';
import propTypes from 'prop-types';
import './Movie.css';

function Movie({title, poster, genres, synopsis}){
    return(
        <div className="Movie">
            <div className="Movie__Columns">
                <MoviePoster poster={poster} alt={title}/>
            </div>

            <div className="Movie__Columns">
                <h1>{title}</h1>
                <div className="Movie__Genres"> 
                    {/* 장르는 array로 들어있어서 Map 통해 전부 출력 */}
                    {genres.map((genre, index) => <MovieGenres genre={genre} key={index}/>)} 
                </div>
                <p className="Movie__Synopsis">
                    {synopsis}
                </p>
            </div>
        </div>
    )
}

function MoviePoster({poster, alt}){
    return(
        <img src={poster} alt="alt" title={alt}/>
    )
}

function MovieGenres({genre}){
    return (
        <span className="Movie__Genre">{genre}</span>
    )
}

Movie.propTypes = {
    title: propTypes.string.isRequired,
    poster: propTypes.string.isRequired,
    genres: propTypes.array.isRequired,
    synopsis: propTypes.string.isRequired
}

MoviePoster.propTypes = {
    poster: propTypes.string.isRequired
}


MovieGenres.propTypes = {
    genre: propTypes.string.isRequired
}

export default Movie //app.js로 해당 컴포넌트를 내보낸다.

2. Css 꾸미기

Css는 노마드 코더의 Css 자료를 사용했다.

/src/App.css

.App {
  padding:50px;
  display: flex;
  justify-content: space-around;
  flex-wrap: wrap;
  font-size:14px;
}

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

/src/Movie.css

.Movie{
    background-color:white;
    width:40%;
    display: flex;
    justify-content: space-between;
    align-items:flex-start;
    flex-wrap:wrap;
    margin-bottom:50px;
    text-overflow: ellipsis;
    padding:0 20px;
    box-shadow: 0 8px 38px rgba(133, 133, 133, 0.3), 0 5px 12px rgba(133, 133, 133,0.22);
}

.Movie__Column{
    width:30%;
    box-sizing:border-box;
    text-overflow: ellipsis;
}

.Movie__Column:last-child{
    padding:20px 0;
    width:60%;
}

.Movie h1{
    font-size:20px;
    font-weight: 600;
}

.Movie .Movie__Genres{
    display: flex;
    flex-wrap:wrap;
    margin-bottom:20px;
}

.Movie__Genres .Movie__Genre{
    margin-right:10px;
    color:#B4B5BD;
}

.Movie .Movie__Synopsis {
    text-overflow: ellipsis;
    color:#B4B5BD;
    overflow: hidden;
}

.Movie .Movie__Poster{
    max-width: 100%;
    position: relative;
    top:-20px;
    box-shadow: -10px 19px 38px rgba(83, 83, 83, 0.3), 10px 15px 12px rgba(80,80,80,0.22);
}

@media screen and (min-width:320px) and (max-width:667px){
    .Movie{
        width:100%;
    }
}

@media screen and (min-width:320px) and (max-width:667px) and (orientation: portrait){
    .Movie{
        width:100%;
        flex-direction: column;
    }
    .Movie__Poster{
        top:0;
        left:0;
        width:100%;
    }
    .Movie__Column{
        width:100%!important;
    }
}

/src/Index.css

body {
  margin: 0;
  padding: 0;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
  background-color:#EFF3F7;
  height: 100%;
}

html, #root{
  height:100%;
}

 

'Archived(Programming) > ReactJS' 카테고리의 다른 글

ReactJS_9_Deploy  (0) 2019.09.21
ReactJS_7_Async_Await  (0) 2019.09.20
ReactJS_6_Fetch_Promise  (0) 2019.09.20
ReactJS_5_Smart_Dumb  (0) 2019.09.20
ReactJS_4_State  (0) 2019.09.18