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 |