No 14. (개정판) ReactJS로 영화 웹 서비스 만들기

Jetom·2022년 3월 18일
2

react

목록 보기
14/15
post-thumbnail

뭐할지 고민하다가 노마드코더를 들어가보니 function component로 영화 웹 서비스를 업데이트 해서 겸사겸사 다시 들었다 😃 오~ 색달라! 여하튼.. 중간중간 블로깅을 했어야했는데.. 어쩌다보니 다 만들고 올린다...ㅎㅎ 🙄
👉 css를 안입힌 최종결과물


//App.js
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import Home from "./routes/Home";
import Detail from "./routes/Detail";

function App() {
  return (
    <Router>
      {/* 스위치는 route를 찾는 역할 */}
      <Switch>
        {/* router에 이 url이 변수를 받을거라고 말해주는것 */}
        <Route path="/movie/:id">
          <Detail />
        </Route>
    	{/*Home이 메인! path="/"를 하면 index 페이지라 생각하면된다.*/}
        <Route path="/">
          <Home />
        </Route>
      </Switch>
    </Router>
  );
}

export default App;

App은 딱히 뭐가 없어서 router만 적고 넘어갔다...


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

function Home() {
  const [loading, setLoading] = useState(true);
  const [movies, setMovies] = useState([]);

  //async, await를 사용할 때
  const getMovies = async () => {
    {/* 👇 async, await를 좀 더 간단하게 표현한것 */}
    const json = await (
      await fetch(
        `https://yts.mx/api/v2/list_movies.json?minimum_rating=8.8&sort_by=year`
      )
    ).json();
    
    {/* 👇 위의 코드를 풀어쓰면 이렇게 된다. */}
    // const res = await fetch(
    //   `https://yts.mx/api/v2/list_movies.json?minimum_rating=8.8&sort_by=year`
    // );

    // const json = await res.json();
    setMovies(json.data.movies);
    setLoading(false);
  };

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

  //fetch를 사용할 때
  // useEffect(() => {
  //   fetch(
  //     `https://yts.mx/api/v2/list_movies.json?minimum_rating=8.8&sort_by=year`
  //   )
  //     .then((res) => res.json())
  //     .then((json) => {
  //       setMovies(json.data.movies);
  //       setLoading(false);
  //     });
  // }, []);

  return (
    <>
    {/* json을 받아오기 전엔 loading이 나오고 다 받아왔다면 정보들을 보여준다! */}
      {loading ? (
        <h1>Loading..</h1>
      ) : (
        <div>
          {movies.map((movie) => (
            <Movie
              key={movie.id}
              id={movie.id}
              coverImg={movie.medium_cover_image}
              title={movie.title}
              summary={movie.summary}
              genres={movie.genres}
            />
          ))}
        </div>
      )}
    </>
  );
}

export default Home;

Home에선 async, await를 사용했는데, 아직 익숙하지가 않아서.. fetch로 쓰는게 좋긴하다....


//Movie.js
import PropTypes from "prop-types";
import { Link } from "react-router-dom";

{/* 이곳에서 props를 받아서 표현해준다. coverImg는 medium_cover_image를 props로 넘겨줄때 coverImg로 넘겨줘서 넘겨준 이름 그대로 받아서 쓴것 */}
function Movie({ coverImg, title, summary, genres, id }) {
  return (
    <div>
      {/* alt를 안쓰면 친절하게 알려준다.. */}
      <img src={coverImg} alt={title} />
      <h2>
    {/* react에서 id에 따라 url을 바꿔주고싶다면 아래와 같이 사ㅛㅇ하면 된다. */}
        <Link to={`/movie/${id}`}>{title}</Link>
      </h2>
      <p<>{summary}</p>
      <ul>
		{/* genres는 없을수도 있을수도 있기 때문에 옵셔널 체이닝을 걸었고, 여러개가 있기에 map을 돌렸당 */}
        {genres?.map((g) => (
          <li key={g}>{g}</li>
        ))}
      </ul>
    </div>
  );
}

{/* id에 string이 들어간다면 너 그렇게 쓰지마! 하고 알려주는 기능 (타입스크립트를 쓴다면 무시해도 될 부분이다.) */}
Movie.prototype = {
  id: PropTypes.number.isRequired,
  coverImg: PropTypes.string.isRequired,
  title: PropTypes.string.isRequired,
  summary: PropTypes.string.isRequired,
  genres: PropTypes.arrayOf(PropTypes.string).isRequired,
};

export default Movie;

🤔 ts를 안쓴다면 prototype도 괜찮은것같당


//Detail.js
import { useEffect, useState } from "react";
import { useParams } from "react-router-dom";

function Detail() {
  const { id } = useParams();
  const [loading, setLoading] = useState(true);
  const [movie, setMovie] = useState([]);

  {/* api에서 id를 기준으로 해당 movie의 정보를 불러오게한다. */}
  const getMovie = async () => {
    const json = await (
      await fetch(`https://yts.mx/api/v2/movie_details.json?movie_id=${id}`)
    ).json();

    setLoading(false);
    
    {/* 불러온 정보를 담아서 나타내주는 준비운동? 같은 느낌*/}
    setMovie(json.data.movie);
  };

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

  return (
    <>
    {/* 정보를 가져오기 전까진 loading이 나오고 가져왔다면 영화 정보들이 나온다. */}
      {loading ? (
        <h1>loading..</h1>
      ) : (
        <div>
          <img src={movie.medium_cover_image} alt={movie.title} />
          <h2>{movie.title}</h2>
          <p>{movie.date_uploaded}</p>
          <ul>
            {movie.genres?.map((g) => (
              <li key={g}>{g}</li>
            ))}
          </ul>
        </div>
      )}
    </>
  );
}
export default Detail;

흠,, 🤔 스타일링을 하면 또 오랫동안 붙잡아둘까봐 기능만 후딱하고 끝내버렸다.. 우선 useEffect의 기능과 useState의 기능을 다시 개념을 잡아보는 시간이여서 좋았다. (하지만 Dynamic Routing은 한번 더 보는거로...😅)

profile
사람이 좋은 인간 리트리버 신혜리입니다🐶

0개의 댓글