카테고리 없음

영화 앱 전체 모습 수정하기

· 코딩마이데이

App.css 내용 모두 지우기

 

노마드 코더 영화 API에서 장르 키 살펴보기

 

Movie 컴포넌트에 genres props 넘겨주기

Movie 컴포넌트 인자에 genres을 추가하고, Moive.propTypes에는 genres props가 문자열 배열 arrayOf(PropTypes.string)이며 반드시 필요함(isRequired)을 추가합시다.

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

const Movie = ({ title, year, summary, poster, genres }) => {
  return (
    <div class="movie">
      <img src={poster} alt={title} title={title} />
      <div class="movie__data">
        <h3 class="movie__title">{title}</h3>
        <h5 class="movie__year">{year}</h5>
        <p class="movie_summary">{summary}</p>
      </div>
    </div>
  );
};

Movie.propTypes = {
  year: PropTypes.number.isRequired,
  title: PropTypes.string.isRequired,
  summary: PropTypes.string.isRequired,
  poster: PropTypes.string.isRequired,
  genres: PropTypes.arrayOf(PropTypes.string.isRequired),
};

export default Movie;

 

영화 앱을 수정한 다음 실행하여 [Console] 탭을 열면 경고 메시지가 나옵니다.

JSX에 사용한 속성 중 class 속성이 className으로 사용되어야 한다는 뜻입니다.

class 속성은 className으로 바꿔주고, genres가 잘 넘어오도록 App.js를 수정합니다.

 

class 속성 이름 className으로 바꿔주기

import axios from "axios";
import React from "react";
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-proxy.now.sh/list_movies.json?sort_by=rating"
    );
    this.setState({ movies, isLoading: false });
  };
  componentDidMount() {
    this.getMovies();
  }

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

    return (
      <section class="container">
        {isLoading ? (
          <div class="loader">
            <span class="loader__text">로딩 중...</span>
          </div>
        ) : (
          <div class="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>
        )}
      </section>
    );
  }
}

export default App;

 

APP 컴포넌트에서 Movie 컴포넌트로 genre props를 넘겨주므로 이제 genre.props가 undefined라는 경고 메시지는 사라졌을 것입니다.

 

class 속성 이름 className으로 바꿔주기

HTML의 class와 자바스크립트의 class라는 이름이 겹치면 리액트가 혼란스러울 수 있으므로 하나는 다른 이름을 써야 하는 기 때문에 className을 사용해야 합니다.

import axios from "axios";
import React from "react";
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-proxy.now.sh/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">로딩 중...</span>
          </div>
        ) : (
          <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>
        )}
      </section>
    );
  }
}

export default App;

 

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

const Movie = ({ title, year, 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>
        <p className="movie_summary">{summary}</p>
      </div>
    </div>
  );
};

Movie.propTypes = {
  year: PropTypes.number.isRequired,
  title: PropTypes.string.isRequired,
  summary: PropTypes.string.isRequired,
  poster: PropTypes.string.isRequired,
  genres: PropTypes.arrayOf(PropTypes.string.isRequired),
};

export default Movie;

 

영화 장르 출력하기

genres props가 배열이므로 map() 함수를 사용할 것입니다. genres props를 ul. li로 엘리먼트로 감싸 출력해 봅시다.

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

const Movie = ({ title, year, 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="movie__genres">
          {genres.map((genre) => {
            return <li className="movie__genre">{genre}</li>;
          })}
        </ul>
        <p className="movie_summary">{summary}</p>
      </div>
    </div>
  );
};

Movie.propTypes = {
  year: PropTypes.number.isRequired,
  title: PropTypes.string.isRequired,
  summary: PropTypes.string.isRequired,
  poster: PropTypes.string.isRequired,
  genres: PropTypes.arrayOf(PropTypes.string.isRequired),
};

export default Movie;

 

 

 

 

 

장르를 출력할 때 사용한 li 엘리먼트에 key props를 추가하지 않아서 그런것입니다.

map() 함수애 전달할 함수에 두 번째 인자를 전달하면 됩니다. map() 함수에 전달할 함수의 2번째 인자에는 map() 함수가 반복 실행하며 반환할 배열 원소의 인덱스가 자동으로 들어옵니다.

이 값을 이용하면 key props를 손쉽게 추가할 수 있습니다.

 

li 엘리먼트에 key props 추가하기

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

const Movie = ({ title, year, 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="movie__genres">
          {genres.map((genre, index) => {
            return (
              <li key={index} className="movie__genre">
                {genre}
              </li>
            );
          })}
        </ul>
        <p className="movie_summary">{summary}</p>
      </div>
    </div>
  );
};

Movie.propTypes = {
  year: PropTypes.number.isRequired,
  title: PropTypes.string.isRequired,
  summary: PropTypes.string.isRequired,
  poster: PropTypes.string.isRequired,
  genres: PropTypes.arrayOf(PropTypes.string.isRequired),
};

export default Movie;