본문 바로가기

React/응용프로젝트

[노마드코더] React로 영화 앱 만들기1

앱 안에서 페이지를 전환하는 방법

먼저 영화 정보를 불러와서 보여줘야함.

1.  영화 정보를 받을 수 있는 api 를 가지고 온댜.

https://yts.mx/api

 

API Documentation - YTS YIFY

Official YTS YIFY API documentation. YTS offers free API - an easy way to access the YIFY movies details.

yts.mx

나는 이 사이트를 쓸것이당.

2. 정보를 불러오는 도중에 보여줄 로딩 창을 구현한다.

import logo from './logo.svg';
import './App.css';
import { useState } from 'react';

function App() {
  const [loading, setLoading] = useState(true);
  return (
    <div className="App">
      {loading ? <h1>Loading...</h1> : null}
    </div>
  );
}

export default App;

먼저 요렇게 useState의 기본값을 true 로 한 뒤, loading 이 true 면

Loading... 이라는 문구가 나오도록 한다.

api 를 한번만 받아오길 원하니까 .. useEffect 를 쓴당.

function App() {
  const [loading, setLoading] = useState(true);
  useEffect(() => {
    fetch(`https://yts.mx/api/v2/list_movies.json?minimum_rating=9`).then((response) => response.json()).then((json) => console.log(json))
  }, [])
  return (

fetch 를 사용해 api 를 갖고온뒤, 콘솔로그에 json 받아온 데이터를 확인해본다.

아주 잘 가져와진 모습.

아직 state 를 바꿔주지 않았기때문에, 로딩중이라고만 나오고 있다.

이제 받아온 데이터를 state 에 넣어줄 것이당.

state 를 만들어주자.

  const [movies, setMovies] = useState([]);

배열로 저장할거당

  useEffect(() => {
    fetch(`https://yts.mx/api/v2/list_movies.json?minimum_rating=9`).then((response) => response.json()).then((json) => setMovies(json.data.movies))
  }, [])

그리고 받아온 데이터를 setMovies 를 이용해 movie 에 넣어주기.

데이터를 받아왔으면 로딩을 false로 만들어줘야함. 로딩이 끝났으니까.

.then((json) => {setMovies(json.data.movies); setLoading(false);

하지만 자바스크립트에서 api 를 불어올 때처

async-await 를 사용하기 위해

getMovies라는 함수를 만들어줄거임.

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

결과물은 이렇다.

자바스크립트 뉴스 api 를 사용할 때처럼 똑같은 방식이다.

이것보다 좀 더 짧게 하는 방법은

  const [movies, setMovies] = useState([]);
  const getMovies = async () => {
    const json = await (await (await fetch(`https://yts.mx/api/v2/list_movies.json?minimum_rating=9`)).json());
    setMovies(json.data.movies);
    setLoading(false);
  }
  useEffect(() => {
    getMovies()
  }, [])

response 에서 다 합쳐버리는거임.

3. 가져온 데이터들을 로딩이 끝난 화면에 보여준다.

map () 함수를 사용할것임.

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

데이터를 받아오는 중이라면, loading ... 이 나오고

데이터를 다 받아온다면, movies 를 map() 함수를 통해 아이템을 하나씩 가져와준다.

div 의 키값은 받아온 데이터에는 각자 아이디가 있으므로

그걸 키값으로 정해준다.

그리고 영화의 제목을 넣어준다.

결과는?

영화 제목들이 잘 나오는 모습이다!

이제 좀 더 많은 정보를 보여줄것이당.

  return (
    <div className="App">
      {loading ? <h1>Loading...</h1> : <div>{movies.map((item) => {
        return <div key={item.id}>
                  <h2>{item.title}</h2>
                  <p>{item.summary}</p>
                </div>
      })}</div>}
    </div>
  );

summary 를 받아왔다. 결과는

좋다좋다!

이제 무슨 장르인지 가져와보자.

장르를 보면 배열로 이루어진 것을 알 수가 있죠?

그래서 이 배열의 map 를 한번 해줄것임.

  return (
    <div className="App">
      {loading ? <h1>Loading...</h1> : <div>{movies.map((item) => {
        return <div key={item.id}>
                  <h2>{item.title}</h2>
                  <p>{item.summary}</p>
                  <ul>
                    {item.genres.map((g) => {
                      return <li key={g}>{g}</li>
                    })}
                  </ul>
                </div>
      })}</div>}
    </div>
  );

ul 안에서 map 을 돌려 나온 장르들이 li 로 나오게끔 해주었당.

키값을 항상 줘야한다. 유니크한 값으로

결과는 이렇게 모든 정보가 잘 나온당!!

이제 커버이미지를 가져와볼까?

medium image 를 가져올거임.

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

img src 에 item 에서 미디움 커버 이미지 주소를 넣어주니

이미지도 잘 나오는 모습을 확인할 수 있당.

다음 글에서는 영화를 클릭하면 영화를 설명해주는 페이지로 넘어가는 기능을 구현할게용