
다이나믹(동적) URL
React Router는 다이나믹 url도 지원한다.
다이나믹하다는 것은, url에 변수를 넣을 수 있다는 뜻이다.
<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을 콘솔창에 찍어보면 영화에 상세 정보를 전달 받을 수 있다.

이제 Detail 스크린에는 로딩이나 다른 것들만 남았다.
그리고 movie가 state에 있지 않다.
API에서 json을 받아와서 사용해야 한다.
그러니까 json을 useState에 넣어주면 되겠다 😚
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;
다음과 같이 해주고, styled-components를 설치하여 간단한 디자인도 하였다 !
홈페이지 영화 설명 길이를 보면 어떤 것은 매우 길고 어떤 것은 매우 짧다.
따라서 이 길이를 좀 조정해주기로 한다.
일단 summary의 이상적인 길이가 어느정도인지 알아내야 한다.
강의에서는 적당해보이는 설명 길이를 .length해서 235자로 제한하기로 했다.
{summary.length > 235 ? "" : summary}
이와 같은 형태로 summary가 235자를 넘지 않는다면, 줄여주고 아니라면 그대로 내보내면 되겠다.
summary는 string이니 array의 method를 사용할 수 있다.
그 중 하나가 .slice() 문법이다.
.slice() 문법은 .slice( 0, 5 ) 이러한 형태를 갖는데,
이는 글자 수 0번째부터 5번째까지만 잘라 보여준다는 뜻이다.
따라서 .slice(0, 235) 라고 해주면 235번째까지 보여줄 수 있겠다.
그리고 그 이후는 .을 3개 사용하여 말줄임표처럼 보이도록 해줬다.
{summary.length > 235 ? `${summary.slice(0, 235)}...` : summary}
그리고 아직 css는 너무 어려워서... 노마드님 css를 받아다가 설정하였다.
노마드님께선 css 모듈을 사용하셨는데 신기했다.
기존에 내가 사용하던 styled-components 랑은 비슷한 듯 다른 느낌..?
막막했던 나의 홈페이지를.. 이렇게 바꿔주셨다.. 체고.. 🥺


추후에 상세페이지도 차차 꾸밀 예정이다 💪