관리 메뉴

공부기록용

ReactJS로 영화 웹 서비스 만들기(07_2/Movie App03_patameters, useParams) 본문

📚강의록📚/노마드)React

ReactJS로 영화 웹 서비스 만들기(07_2/Movie App03_patameters, useParams)

과부하가즈아 2023. 7. 20. 20:54

https://nomadcoders.co/react-for-beginners/lobby

 

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

왕초보를 위한 React

nomadcoders.co


받아온 url의 data대로 title를 클릭하면 알맞은 내용이 보이도록 하겠다.

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

function App() {
  return (
    <Router>
      <Routes>
        <Route path="/" element={<Home />}></Route>
        <Route path="/movie/:id" element={<Detail />}></Route>
      </Routes>
    </Router>
  );
}
export default App;
<Route path="/movie/:id" element={<Detail />}></Route>

 

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

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=8.8&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
              key={movie.id}
              coverImage={movie.medium_cover_image}
              title={movie.title}
              summary={movie.summary}
              genres={movie.genres}
              id={movie.id}
            />
          ))}
        </div>
      )}
    </div>
  );
}

export default Home;
id={movie.id}

> id라는 이름으로 movie의id를 movie.js에 보내준다.

 

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

function Movie({ coverImage, title, summary, genres, id }) {
  return (
    <div>
      <img src={coverImage} alt="{title}" />
      <h2>
        <Link to={`/movie/${id}`}>{title}</Link>
      </h2>
      <p>{summary}</p>
      <ul>
        {genres.map((g) => (
          <li key={g}>{g}</li>
        ))}
      </ul>
    </div>
  );
}

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

export default Movie;
{ coverImage, title, summary, genres, id }

> 부모 컴포넌트인 Home.js에서 받아온 id={movie.id}의 id_숫자 값을

 

 <h2>
  <Link to={`/movie/${id}`}>{title}</Link>
</h2>

> 파라미터 끝단에 달아준다. 

 

 id: PropTypes.number.isRequired,

> id의 타입 역시 지정해 준다. 


id값이 무엇인지, url에 있는 값을 반환해주는 함수_hook, useParams

<Route path="/movie/:id" element={<Detail />}></Route>

> 에서 :id 이 url이 변수를 받는 것이다. 

 

import { useParams } from "react-router-dom";

function Detail(){

    const x = useParams();
    console.log(x)

    return <h1>Detail</h1>
}

export default Detail;

> x로써 :id를 받는 것이다

<Route path="/movie/:tomato" element={<Detail />}></Route>

> :tomato로 변수를 지정한다면 x로써 :tomato를 받아서 다음과 같이 나타나게 된다. 


id로 받아와서 콘솔에 찍어보기

import { useParams } from "react-router-dom";

function Detail(){

    const {id} = useParams();
    console.log(id)

    return <h1>Detail</h1>
}

export default Detail;

 

> 해당 id값만 나타나는 것 확인


같은 방식으로 title 클릭시 넘어가는 페이지에 다시 id에 맞는 내용을 받아 올 수 있게 하기

페이지는 Detail로 정하고, 그 페이지의 component는 DetailMovies로 하기로 함


// DetailMovies.js
import PropTypes from "prop-types";


function DetailMovies({ coverImage, title, genres }) {
  return (
    <div>
      <img src={coverImage} alt="{title}" />
      <h2>{title}</h2>
      <ul>
        {genres.map((g) => (
          <li key={g}>{g}</li>
        ))}
      </ul>
    </div>
  );
}

DetailMovies.propTypes = {
  coverImage: PropTypes.string.isRequired,
  title: PropTypes.string.isRequired,
  genres: PropTypes.arrayOf(PropTypes.string).isRequired,
  id: PropTypes.number.isRequired,
};

export default DetailMovies;
// Detail.js
import DetailMovies from "components/DetailMovie";
import { useEffect, useState } from "react";
import { useParams } from "react-router-dom";

function Detail() {
  const { id } = useParams();

  const [details, setDetails] = useState([]);

  const getMovie = async () => {
    const json = await (
      await fetch(`https://yts.mx/api/v2/movie_details.json?movie_id=${id}`)
    ).json();
    //console.log(json.data.movie)
    setDetails([json.data.movie]);
  };

  useEffect(() => {
    getMovie();
  }, []);
  console.log(details);

  return (
    <div>
      {Array.isArray(details) ? (
        <div>
          {details.map((detail) => (
            <DetailMovies
              key={detail.id}
              coverImage={detail.medium_cover_image}
              title={detail.title}
              genres={detail.genres}
              id={detail.id}
            />
          ))}
        </div>
      ) : null}
    </div>
  );
}

export default Detail;

> 해당 API로 데이터를 불러오니 배열이 아닌 객체로 받아와져셔

> 데이터를 받는 details를 [ ]로 저장할 수 있도록 setDetails([json.data.movie]) 이렇게 진행함_그래야 map을 쓸 수 있음

> Array.isArray(details) ?라는 조건을 걸어서 배열이어야만 map으로 요소를 돌면서 출력할 수 있게함

Comments