본문 바로가기

프론트엔드/ReactJS 시작하기

[React] Movie App - API로부터 JSON 가져오기 예제(2) by useEffect, useState

이번 포스팅에서는 영화와 영화에 대한 정보를 브라우저에서 보여주고 링크를 넣어서 그 영화에 대해 더 많은 정보를 찾아볼 수 있도록 다른 곳으로 연결시켜주는 프로젝트를 만들어보겠습니다.

영화 정보를 받을  api : 

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

-> 평점이 8.5이상이고 연도별로 정렬

영화 API JSON

#api에서 가져온 json => 영화 정보는 json.data.movies에 있음

 

작성한 코드

import { useEffect, useState } from "react";


function App() {
  const [loading, setLoading] = useState(true) 
  const [movie, setMovie]=useState([])
  // [] => 코드 딱 한번만 작성
  useEffect(()=>{
    fetch("https://yts.mx/api/v2/list_movies.json?minimum_rating=8.5&sort_by=year")
    .then(response => response.json())
    .then(json=>{
      setMovie(json.data.movies)
      setLoading(false)
     });
  },[])
  console.log(movie)
  return (
   <div>
      
      {loading?<h1>Loading...</h1>:null}
      
   </div>
  );
}

export default App;

결과

 

useEffect 내에서 then을 사용하지 않고 async-await을 사용하기 위해 getMovies라는 함수를 만들어보겠습니다.

import { useEffect, useState } from "react";


function App() {
  const [loading, setLoading] = useState(true) 
  const [movie, setMovie]=useState([])
  const getMovies = async() => {
    const response = await fetch(
      'https://yts.mx/api/v2/list_movies.json?minimum_rating=8.5&sort_by=year'
    )
    const json = await response.json()
    setMovie(json.data.movies)
    setLoading(false)
  }
  console.log(movie)
  useEffect(()=>{
    getMovies();
  },[])
  return (
   <div>
      
      {loading?<h1>Loading...</h1>:null}
      
   </div>
  );
}

export default App;

#await이 then을 대신합니다

이번에는 브라우저에 영화리스트와 정보를 출력해보도록 하겠습니다.

import { useEffect, useState } from "react";


function App() {
  const [loading, setLoading] = useState(true) 
  const [movies, setMovies]=useState([])
  const getMovies = async() => {
    const json = await (
      await fetch(
        'https://yts.mx/api/v2/list_movies.json?minimum_rating=8.5&sort_by=year'
      )
    ).json()
    setMovies(json.data.movies)
    setLoading(false)
  
  }
  console.log(movies)
  useEffect(()=>{
    getMovies();
  },[])
  return (
   <div>
     {loading ? <h1>Loading...</h1> :
      <ul>
        {movies.map((movie)=>(
          <li key={movie.id}>
         	<img src={movie.medium_cover_image}/>
            <h2>{movie.title}</h2>
            <p>{movie.summary}</p>
          </li>
          
        ))}
      </ul>
     }
      
     
       
   </div>
  );
}

export default App;

결과

 

#json에서 영화 장르도 가져올건데 장르는 array이기 때문에 map을 한번 더 사용해서 가져와야합니다.

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

#결과

 

마지막으로 Movie 컴포넌트를 만들어서 코드를 따로 관리하겠습니다.

#App.js

import { useEffect, useState } from "react";
import Movie from "./Movie";


function App() {
  const [loading, setLoading] = useState(true) 
  const [movies, setMovies]=useState([])
  const getMovies = async() => {
    const json = await (
      await fetch(
        'https://yts.mx/api/v2/list_movies.json?minimum_rating=8.5&sort_by=year'
      )
    ).json()
    setMovies(json.data.movies)
    setLoading(false)
  
  }
  console.log(movies)
  useEffect(()=>{
    getMovies();
  },[])
  return (
   <div>
     {loading ? <h1>Loading...</h1> :
      <div>
        {movies.map((movie)=>(
          <Movie 
            coverImg={movie.medium_cover_image}
            title={movie.title}
            summary={movie.summary}
            genres={movie.genres} />
          
        ))}
      </div>
     }
   </div>
  );
}

export default App;

 

#Movie.js (Movie 컴포넌트)

import PropTypes from "prop-types";

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

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

export default Movie

 

 

다음 포스팅에서 영화를 클릭했을 시 더 자세한 정보를 알 수 있는 페이지로 전환하는 방법을 알아보겠습니다!