💻 Study/웹

#4 MAKING THE MOVIE APP

soyang. 2021. 1. 10. 04:15
728x90

4.0 Fetching Movies from API

fetch

 

axios

: fetch위에 있는 작은 layer

axios 설치

npm i axios

 

더보기

사용할 API

: YTS-proxy API (by nomad coder)

yts.mx/api/v2/list_movies.json

 

JsonView - json파일을 예쁘게 보여주는 크롬 확장프로그램

: https://chrome.google.com/webstore/detail/jsonview/chklaanhfefbnpoihckbnefhakgolnmc/related

 

axios로 가져온 data를 변수에 저장

axios가 우리에게 data를 주지만, 우리는 그 데이터를 잡아야 한다. 그래야 state에 사용 가능.

componentDidMount(){
    const movies =  axios.get("https://yts.mx/api/v2/list_movies.json");
  };

axios는 느릴 수 있다.

따라서, Javascript에게 componentDidMount function이 끝날 때까지 약간 시간이 걸릴 수 있다고 알려야 한다.

이를 위해 componentDidMount 앞에 async를 넣는다.

 async componentDidMount(){
    const movies =  axios.get("https://yts.mx/api/v2/list_movies.json");
  };

또는 function을 만든다. (Better react)

getMovies = async () => {
    const movies =  await axios.get("https://yts.mx/api/v2/list_movies.json");
  }
  componentDidMount(){
    this.getMovies();
  };

- asnyc: 이 함수는 비동기(async)이다. "너는 기다려야 함"

- await ___: ___를 기다려야 한다.

+ async가 없다면 await 키워드를 사용할 수 없다!

+ async, await하지 않으면, js는 function을 기다려주지 않을 것이다.


4.1 Rendering the Movies

API에서 읽어온 data에서 movies 뽑아내기

// Not Sexy
const movies = await axios.get("https://yts.mx/api/v2/list_movies.json");
console.log(movies.data.data.movies);

// Sexy -> Do this way
const {data: { data : {movies}}} = await axios.get("https://yts.mx/api/v2/list_movies.json");
console.log(movies);
const {
  data: {
    data : { movies }
  }
} = await axios.get("https://yts.mx/api/v2/list_movies.json");
// this.setState({movies:movies}) // state:axios
// this.setState({ movies }) // summarize
this.setState({ movies, isLoading: false })

- javascript에서 이름이 같은 경우, 단축해서 쓸 수 있다.

- 한 번에 setState 여러 개 가능

 

movies를 render!

If component가 state가 필요없을 경우:

class component가 될 필요없다. -> function component!

// src/Movie.js
import React from "react";
import PropTypes from "prop-types"

function Movie(id, year, title, summary, poster){
    return <h4>{title}</h4>;
}

Movie.propTypes = {
    id: PropTypes.number.isRequired,
    year: PropTypes.number.isRequired,
    title: PropTypes.string.isRequired,
    summary: PropTypes.string.isRequired,
    poster: PropTypes.string.isRequired
};

export default Movie;
render(){
    const { isLoading, movies } = this.state;
    return (
      <div>
        {isLoading 
        ? "Loading..." 
        : movies.map(movie => (
            <Movie 
              key={movie.id}
              id={movie.id} 
              year={movie.year} 
              title={movie.title} 
              summary={movie.summary} 
              poster={movie.medium_cover_image}
            />
          ))}
      </div>
    );   
  }
map은 반드시 무언가 return해줘야 한다!

4.2 Styling the Movies

  • css 파일을 import
  • HTML element에 style={{}}을 적용
import React from "react";
import axios from "axios";
import Movie from "./Movie";
import "./App.css";

class App extends React.Component{
  state = {
    isLoading: true,
    movies: []
  };
  getMovies = async () => {
    const {
      data: {
        data : { movies }
      }
    } = await axios.get(
      "https://yts.mx/api/v2/list_movies.json/sort_by=rating"
    );
    this.setState({ movies, isLoading: false });
  };   componentDidMount() {
    this.getMovies();
  }
  render() {
    const { isLoading, movies } = this.state;
    return (
      <section className="container">
        {isLoading ? (
          <div className="loader">
            <span className="loader__text">Loading...</span>
          </div>
        ) : (
          <div className="movies">
            {movies.map(movie => (
              <Movie
                key={movie.id}
                id={movie.id}
                year={movie.year}
                title={movie.title}
                summary={movie.summary}
              />
            ))}
          </div>
        )}
      </section>
    );
  }
}
  
export default App;
import React from "react";
import PropTypes from "prop-types";
import "./Movie.css"

function Movie({ year, title, summary, poster }) {
  return (
    <div className="movie">
      <img src={poster} alt={title} title={title} />
      <div className="movie__data">
          <h3 className="movie__title">
            {title}
          </h3>
          <h5 className="movie__year">{year}</h5>
          <p className="movie__summary">{summary}</p>
      </div>
    </div>
  );
}
  
Movie.propTypes = {
  id: PropTypes.number.isRequired,
  year: PropTypes.number.isRequired,
  title: PropTypes.string.isRequired,
  summary: PropTypes.string.isRequired,
  poster: PropTypes.string.isRequired
};
  
export default Movie;

4.3 Adding Genres

📌 className VS class
HTML에서 class는 class이다.
BUT 이 코드는 JSX이다.javascript class 안에 있으면 component class에 의해 혼란스러워 진다.
따라서, className으로 사용한다.

+ 개발자 도구에서 해당 element를 확인하면, className은 class로 표시된다.

genres는 string의 array형태로 저장되어 있다.

-> map을 사용!

- PropTypes.arrayOf(PropTypes.string)으로 proptypes를 검사

function Movie({ year, title, summary, poster, genres }) {
  return (
    <div className="movie">
      <img src={poster} alt={title} title={title} />
      <div className="movie__data">
          <h3 className="movie__title">{title}</h3>
          <h5 className="movie__year">{year}</h5>
          <ul className="genres">
            {genres.map((genre, index) => (
              <li key={index} className="genres__genre">{genre}</li>
            ))}
          </ul>
          <p className="movie__summary">{summary}</p>
      </div>
    </div>
  );
}
  
Movie.propTypes = {
  id: PropTypes.number.isRequired,
  year: PropTypes.number.isRequired,
  title: PropTypes.string.isRequired,
  summary: PropTypes.string.isRequired,
  poster: PropTypes.string.isRequired,
  genres: PropTypes.arrayOf(PropTypes.string).isRequired
};

App.js

- genres를 전달

<div className="movies">
    {movies.map(movie => (
    	<Movie
            key={movie.id}
            id={movie.id}
            year={movie.year}
            title={movie.title}
            summary={movie.summary}
            poster={movie.medium_cover_image}
            genres={movie.genres}
        />
    ))}
</div>

4.4 Styles Timelapse

그냥 style(css) 적용하는 거 말 1도 안 하고 timelapse로 보여주신 편입니다.


4.5 Cutting the summary

summary의 길이가 모두 다르므로 똑같이 만들기

const summary = "kadflasmvwajepvdaks awjdkv poeqkw;lfcnv apjewklj sdalkjsalmvalsdjwfp";

// summary의 길이
summary.length

// start ~ end 반환
summary.slice(start, end)
// Movie.js에서 적용
<p className="movie__summary">{summary.slice(0, 180)}...</p>

길이가 모두 180이 된 summary

 

 

📌 다음 강좌: Cloud에 올려 친구나 가족이 볼 수 있게 하기
728x90