whatisthis?

React JS - Movie App project (part 2) 본문

PROJECT/WEB

React JS - Movie App project (part 2)

thisisyjin 2022. 2. 19. 15:12
 

React JS - Movie App project (part 1)

React JS Movie App (part 1) step1. API fetch 하고 / loading창 만들기 import { useEffect, useState } from "react"; function App() { const [loading, setLoading] = useState(true); useEffect(() => { fet..

mywebproject.tistory.com

🔺 지난번 진행사항

- fetch(async-await 이용) API

- Arr.map() 으로 각 요소 렌더링

 

 

지금까지의 코드 🔻

App.js

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>
      ) : (
        <div>
          {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(genre => (
                  <li key={genre}>{genre}</li>
                ))}
              </ul>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

export default App;

React JS Movie App (part 2)

** react JS에서 페이지 전환하는 방법

 


 

📌 [ 컴포넌트 분리 + props 이용 ]

 

우선 Movie.js 파일 생성 후 ,Movie 컴포넌트 생성.

 

- props를 사용해서

부모 컴포넌트에서 지정해준 prop을 불러올 수 있음!

 

 

Movie.js

function Movie({ coverImg, title, summary, genres }) {     // props
  return (
    <div>
      <img src={coverImg} alt={title} />
      <h2>{title}</h2>
      <p>{summary}</p>
      <ul>  
        {genres.map(genre => (
          <li key={genre}>{genre}</li>
        ))}
      </ul>
    </div>
  );
}
export default Movie;
왜 여기선 key를 안썼는지?
- key값은 React.js안에서만, map() 안에서 component들을 렌더링할 때 필요한 것.
즉, 여기선 컴포넌트를 Movie.js로 분리했으므로 key prop을 줄 필요는 없다.

 

 

App.js

// 생략
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>
  );

 

works!

 

 

 

 

props를 사용했으니, type을 검사해주는

propTypes를 적용시켜보자!

 

우선 import를 하고,

import PropTypes from "prop-types";

다음과 같이 각 prop에 대한 타입을 적어준다.

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

arrayOf(string)은 스트링으로 구성된 배열이라는 의미이다.

 

 

Movie.js 전체코드 🔻

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;

 


 

 

📌 [ React Router ]

 

- 페이지를 전환해주는 기능

npm install react-router-dom

터미널 창에 위 코드를 입력해서 설치함.

 

우리는 이제부터 스크린(screen), 즉 라우트(route)  단위로 생각해야함.

예> 하나의 route = 홈/ 홈스크린 / 홈페이지 

 

 

 

우선 컴포넌트를 나눠보자.

 

1 / src폴더에 새 폴더 두개 생성 (components / routes)

2 / components에 Movie.js를 옮겨 넣음.

3 / routes에는 Home.js를 생성한 후, App.js의 코드를 그대로 복붙함

4 / App.js 는 return null로 우선 바꿔놓고, 

모든 파일의 import 부분+ export default를 수정함.

 

디렉토리 구성

 

전체 코드 구성 🔻

더보기

Home.js

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

function Home() {
  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>
      ) : (
        <div>
          {movies.map(movie => (
            <Movie
              coverImg={movie.medium_cover_image}
              title={movie.title}
              summary={movie.summary}
              genres={movie.genres}
            />
          ))}
        </div>
      )}
    </div>
  );
}

export default Home;

 

Movie.js

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;

 

 

 App.js

function App() {
  return null;
}

export default App;

 

 

여기까지 했다면, /route 폴더에 Detail.js 파일을 새로 생성.

function Detail() {
  return <h1>Detail</h1>;
}
export default Detail;

 

다음시간엔 React Router로 연결하는 방법 구현함.

 

 

 

 

home 라우트(페이지)모든 영화를 보여주고,
Movie 라우트는 영화 하나만 보여줌.
home 라우트는 기본적으로 App 컴포넌트 전체를 가지고 있게 만듦.

 


 

Ref. 

Free Lecture

 

 

ReactJS로 영화 웹 서비스 만들기 – 노마드 코더 Nomad Coders

React Fundamentals

nomadcoders.co