[React] useParams , id

hyeryeon·2024년 2월 25일
post-thumbnail
<Route path="/movie/:id" element={<Detail />} />

영화마다 각자 다른 id를 가질 것이다.
따라서 이렇게 /movie 뒤에 /:id 를 넣어 각자 다른 영화들을 받아주게 해준다.

이제 Movie 컴포넌트에서 props를 id로 받게 변경해줘야 한다.

따라서 Home 컴포넌트로 가서 id={movie.id} 한 줄을 추가시키면 된다.

그리고 Movie 컴포넌트의 Link to="/movie">{title}/Link> 를

Link to={/movie/${id}}>{title}/Link> 로 id를 받아오게 변경해준다.

그럼 이런 식으로 영화마다 각자 다른 id 값이 넘어오는 것을 볼 수 있다.

남은 것은 정확한 id를 알아내는 것이다.
어떤 id가 오는지 알아내면 fetch url에 정확한 id 값을 줄 수 있다.
다행히도 React Router에선 이 url에 있는 값을 반환해주는 useParams 함수가 있다.

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

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

export default Detail;

Detail 컴포넌트로 가서 useParams를 다음과 같이 사용하고 콘솔창을 찍어보면
주소창에 뜨는 id와 콘솔창에 뜨는 id가 일치한 것을 볼 수 있다.

이제 남은 것은 받은 id를 가지고 API에 요청을 보내는 것이다.

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

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

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

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

  return <h1>Detail</h1>;
}

export default Detail;

await 는 async 함수 안에서 사용해야해서 따로 함수를 만들었고, useEffect 안에 넣어줬다.

그리고 json을 콘솔창에 찍어보면 영화에 상세 정보를 전달 받을 수 있다.

🚩최종 코드

import { useEffect, useState, useCallback } from "react";
import { useParams } from "react-router-dom";
import styled from "styled-components";

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

  const getMovie = useCallback(async () => {
    const json = await (
      await fetch(`https://yts.mx/api/v2/movie_details.json?movie_id=${id}`)
    ).json();
    setMovie(json.data.movie);
    setLoading(false);
  }, [id]);
  useEffect(() => {
    getMovie();
  }, [getMovie]);

  return (
    <MainSection>
      {loading ? (
        <h1>Loading...</h1>
      ) : (
        <div>
          <img src={movie.large_cover_image} alt="poster" />
          <p>
            🎬 Title: {movie.title}, {movie.year}
          </p>
          <p>✅ Download: {movie.download_count}</p>
        </div>
      )}
    </MainSection>
  );
}

const MainSection = styled.div`
  position: relative;
  text-align: center;
  h1 {
    margin-top: 360px;
  }
`;

export default Detail;

참고블로그

0개의 댓글