[ReactJS로 영화 웹 만들기 ]7. 영화 앱 만들기(promise가 아닌 async await로 fetch url 하기)

이민선(Jasmine)·2022년 12월 16일
0
post-thumbnail

API Url

https://yts.mx/api/v2/list_movies.json?minimum_rating=8&sort_by=year

minimum rating을 지정할 수도 있다. 8 넘으면 뭐 볼만하지(영알못) 나는 8로 지정했다!

뻬치 유알엘 !

useEffect(() => {
    fetch(
      "https://yts.mx/api/v2/list_movies.json?minimum_rating=8&sort_by=year"
    )
      .then((response) => response.json())
      .then((json) => setMovies(json.data.movies));
  }, []);

어제랑 오늘 비동기 빡공했으니 복습을 좀 해보자면,
fetch로 url을 받아온 결과 값이 response이고, 이 response는 string type으로 되어 있다.
json()은 이러한 문자 형태의 response를 object형태로 반환해줌.
그리고 나서 object타입의 json을 받아와서 movie의 state을 변경하겠다는 뜻!

물론 useEffect를 썼고, 두 번째 인자는 빈 배열이므로 앱 최초 렌더링 시 한 번 만 실행되는 함수이다.

console창에 확인되는 나의 사랑스런 object~

아쉽게도 아는 영화는 암 것도 없다.. 영알못의 슬픔..

<async await 사용해보기>

익숙한 코드(promise 사용)

  useEffect(() => {
    fetch(
      "https://yts.mx/api/v2/list_movies.json?minimum_rating=8&sort_by=year"
    )
      .then((response) => response.json())
      .then((json) => {
        setMovies(json.data.movies);
        setLoading(false);
      });
  }, []);

async await를 사용하여 코드를 깔끔하게 바꿔보자.

  const getMovies = async () => {
    const response = await fetch(
      "https://yts.mx/api/v2/list_movies.json?minimum_rating=8&sort_by=year"
    );
    const json = await response.json();
    setMovies(json.data.movies);
    setLoading(false);
  };
  
    useEffect(() => {
    getMovies();
  }, []);
  

코드를 김밥처럼 말아보자.

  const getMovies = async () => {
    const json = await (
      await fetch(
        "https://yts.mx/api/v2/list_movies.json?minimum_rating=8&sort_by=year"
      )
    ).json();
    setMovies(json.data.movies);
    setLoading(false);
  };

  useEffect(() => {
    getMovies();
  }, []);

async await으로 코드를 깔끔하게 만들 수 있다.

다음으로는 map을 이용하여 화면에 영화 제목들을 나타내보자.

return (
    <div>
      {loading ? (
        <h1>Loading...</h1>
      ) : (
        movies.map((movie) => <div key={movie.id}>{movie.title}</div>)
      )}
    </div>
  );

img, h2, p, ur과 li 태그 를 사용하여 영화 별로 포스터, 요약, 장르도 나타낼 수 있다.

return (
    <div>
      {loading ? (
        <h1>Loading...</h1>
      ) : (
        movies.map((movie) => (
          <div key={movie.id}>
            <img src={movie.medium_cover_image} />
            <h2>{movie.title}</h2>
            <p>{movie.summary}</p>
            <ul>
              {movie.genres.map((g) => (
                <li key={g}>{g}</li>
              ))}
            </ul>
          </div>
        ))
      )}
    </div>
  );

연도도 추가하고 내친 김에 9점 이상 짜리 영화로 바꿔보았다.
url에서 최소 평점을 8만 9로 바꾸면 되지롱!

그런데 return 하는 부분이 지저분하므로 다른 파일로 따로 빼줄 수가 있다.
prop을 이용하는 것이지!

Movie.js 파일을 만든 다음
prop type까지 지정해주자.

import PropTypes from "prop-types";

function Movie({ coverImg, title, summary, genres, year }) {
  return (
    <div>
      <img src={coverImg} alt={title} />
      <h2>{title + " (" + year + ")"}</h2>
      <p>{summary}</p>
      <ul>
        {genres.map((g) => (
          <li key={g}>{g}</li>
        ))}
      </ul>
    </div>
  );
}

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

export default Movie;

기존 App.js의 return 부분은 Movie라는 prop을 사용하여 더 깔끔하게 바꿀 수 있다.

return (
    <div>
      {loading ? (
        <h1>Loading...</h1>
      ) : (
        movies.map((movie) => (
          <Movie
            key={movie.id}
            coverImg={movie.medium_cover_image}
            title={movie.title}
            summary={movie.summary}
            genres={movie.genres}
            year={movie.year}
          />
        ))
      )}
    </div>
  );

깔-끔
map 안에서 component들을 렌더링하려면 반드시 key를 줘야한다는 걸 잊지 말자!

다음 게시물에서는 라우터에 대해 다뤄본다!

profile
기록에 진심인 개발자 🌿

0개의 댓글