본문 바로가기
React study/React JS로 영화 웹 서비스 만들기

[React] 7-6. React로 영화 앱 만들기 (4) (dynamic URL 사용해보기)

by 카누가 좋아요 2023. 6. 7.

📌 다이나믹 url 사용해보기

React Router에서는 다이나믹(동적) url을 지원해준다.


✔️ 다이나믹 url

url에 변수를 넣는 경우를 말한다.

ex) http://localhost:3000/movie/12 에서 12 주목!


우리는 user가 어떤 영화의 제목을 클릭하면 http://localhost:3000/movie/{특정 movie의 id} 로 주소를 이동하는 코드를 작성해 볼 것이다.


그러기 위해서는 아래와 같이 route에서 path를 수정한다.


function App() {
  return (
    <Router>
      <Routes>
        <Route path="/movie/:id" element={<Detail />} />     // 주목!
        .....

Detail 컴포넌트를 보여주는 path에 '/movie/:id'라고 적어주었는데, :id라고 적을 경우 그 자리에 1이든 2든 우리가 원하는 무엇이든지 그 자리에 들어갈 수 있다.

* 그냥 id라고만 적게 되면 말 그대로 /movie/id 주소로 이동하므로 :를 꼭 붙여서 적어야 함!


그런데 Movie 컴포넌트에서는 props로 id를 받고 있지 않다.

그 말은 Movie 컴포넌트의 부모 컴포넌트를 살펴보아야 한다는 의미이므로 Home 컴포넌트로 이동하여 그 안에 적혀 있는 Movie 컴포넌트를 살펴보자.

거기에서 Home이 Movie 컴포넌트에서 아래와 같이 id prop을 넘겨주고 있지 않은 것을 확인할 수 있다.


// Home 컴포넌트에서의 코드 중 일부
<Movie
  key={movie.id}
  coverImg={movie.medium_cover_image}
  title={movie.title}
  summary={movie.summary}
  genres={movie.genres}
/>

따라서 id를 속성으로 추가해주면 된다.


<Movie
  key={movie.id}
  id={movie.id} // 주목!
  coverImg={movie.medium_cover_image}
  title={movie.title}
  summary={movie.summary}
  genres={movie.genres}
/>

Movie 컴포넌트에서도 prop를 추가해준다.


function Movie({ id, coverImg, title, summary, genres }) {     // id 주목!
  return (
    <div>
      <img src={coverImg} alt={title} />
      <h2>
        <Link to={`/movie/${id}`}>{title}</Link>     // 주목!
        .....

Movie.propTypes = {
  id: PropTypes.number.isRequired,     // 주목!
  .....

결과로 영화 제목을 클릭하면 http://localhost:3000/movie/51819 이런 식으로 마지막 부분에 해당 영화의 id가 붙은 주소로 이동한다.

그리고 똑같이 모두 Detail 컴포넌트가 실행되어 Detail 문구가 화면에 뜨는 것을 볼 수 있다.


* props는 object일 뿐이고, 우리는 그걸 열어서 item을 꺼내 쓰는 것이다.


우리가 사용한 movie API 주소에 movie id를 입력하면 그 영화에 대한 상세 정보를 알아내는 것이 가능하므로 React Router한테 사용자가 클릭한 영화 제목과 이어지는 주소에 적혀 있는 id부분이 무엇인지를 얻어내야 한다.


✔️ useParams


react router에서는 url에 있는 값을, 특히 변수값을 반환해주는 함수를 제공해준다. 그 함수가 바로 'useParams' 이다.


Detail.js에 다음과 같이 코드를 작성하여 useParams는 어떤 값을 가지고 오는지 확인해 보자.


.....
function Detail() {
  const x = useParams();
  console.log(x);
  return <h1>Detail</h1>;
}
.....

영화 제목을 클릭하면 결과로 {id: '51819'} 이런 식으로 console 창에 뜨는 것을 볼 수 있다.

따라서 다음과 같이 좀 더 직관적으로 알아볼 수 있게 { id }로 적어준다.

그러면 id값이 id 변수에 저장되게 된다.


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

function Detail() {
  const { id } = useParams();
  console.log(id);
  return <h1>Detail</h1>;
}

export default Detail;

이제 우리가 받은 id를 가지고 API에 요청을 보내는 일을 하면 된다.


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

function Detail() {
  const { id } = useParams();
  const getMoive = async () => {
    // 주목!
    const json = await (
      await fetch(`https://yts.mx/api/v2/movie_details.json?movie_id=${id}`)
    ).json();
    console.log(json);
  };
  useEffect(() => {
    // 주목!
    getMoive();
  }, []);
  return <h1>Detail</h1>;
}

export default Detail;

결과로 어떤 영화 제목을 클릭하면 http://localhost:3000/movie/해당영화id 로 넘어가면서 콘솔창에 객체가 하나 뜨게 되는데, 해당 영화에 대한 구체적인 정보가 data 객체에 나타나게 된다.



이제 Detail 페이지에도 Home 페이지처럼 loading을 만드는 것이 좋을 것이다.

그리고 API에서 json을 받아와서 아무것도 하고 있지 않다. 그리고 movie 또한 state에 존재하지 않으므로 movie_details에서 받아온 json 파일 또한 state에 넣는 식으로 코드를 작성하는 것이 좋을 것 같다.



react에서의 핵심은 state, setState, useEffect, useState, props 이다!

댓글