[React] ReactJS로 영화 웹 서비스 만들기

hyeryeon·2024년 2월 25일
post-thumbnail

🎬 Movie App

이 프로젝트는 영화에 대한 정보를 보여주고, 링크를 넣어서 클릭 시
영화에 대한 상세정보를 보여줄 수 있도록 앱에서 다른 곳으로 연결을 시켜줄 예정이다.

지금까지는 하나의 상호작용이 있는 스크린은 만들었지만,
페이지를 전환하는 방법은 다루지 않았다.

첫 번째로는 일단 모든 영화들을 보여주는 것이다.

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

coin tracker 와 마찬가지로 영화들의 정보가 담겨있는 API를 가져올 것이다.

import { useEffect, useState } from "react";

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

  console.log(movies);

  return <div>{loading ? <h1>Loading...</h1> : null}</div>;
}

export default App;

여기서 요즘 보편적으로 then 대신 async-await을 사용하는 편이다.
그 전에 먼저 getMovies라는 async 함수를 만들어주고 useEffect로 불러준다.

다음과 같이 사용한다.

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=9&sort_by=year"
      )
    ).json();
    setMovies(json.data.movies);
    setLoading(false);
  };

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

  console.log(movies);

  return <div>{loading ? <h1>Loading...</h1> : null}</div>;
}

export default App;

return 된 값 안에 null 을 movies.map 으로 넣어주면 되겠다.

이름은 아무거나 지어도 상관없지만 moive라고 짓는 것이 무난할 것 같다.

moives 안에 있는 item들을 map 안에 moive라고 지은 관련 정보 return 값을 받아오는 것이다.

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=9&sort_by=year"
      )
    ).json();
    setMovies(json.data.movies);
    setLoading(false);
  };

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

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

export default App;

그리고 정말 좋은 item 들이 많기 때문에 더 많이 정보를 나타낼 것이다.

기본적으로 제목, 이미지, 장르 등을 따와서 movie. 로 연결시켰다.

이미지는 html 형식과 같게 img 태그를 사용하여 넣어주었다.

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=9&sort_by=year"
      )
    ).json();
    setMovies(json.data.movies);
    setLoading(false);
  };

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

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

export default App;

detail page

이제 영화를 클릭 시, 그 클릭된 영화에 대해 자세한 정보를 나타내도록 해보자

먼저, 현재 작성한 코드들을 따로 Moive 컴포넌트로 만들어 넣어두자.

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

export default Movie;

이 경우에는 key 값이 필요없기 때문에 지웠고,
App.js 에서 받아올 것이기에 movie. 을 지워줬다.

그리고 받아오기 위해 Movie() 안에 props 값을 열어준다.
Moive 컴포넌트는 이 properties 를 다 부모 컴포넌트로부터 받아온다.

이제 App.js로 돌아와 movie를 render해준다.

{movies.map((movie) => (
            <Movie />
          ))}

이렇게만 한다면, Movie.js로 properties를 보내지 않아서 render가 진행되지 않는다.

보낼 이름은 자유롭게 지어도 상관없으나, data 값은 그대로 적어줘야한다.

{movies.map((movie) => (
            <Movie
			  key={movie.id}
              coverImg={movie.medium_cover_image}
              title={movie.title}
              summary={movie.summary}
              genres={movie.genres}
            />
          ))}

0개의 댓글