React를 연습하면서 route 경로를 짤 때 다음 같은 경로를 설정하는 방법이 있었다.
:
이게 뭔 의미일까? 사실 연습하면서 어떻게 이용되는지 봤기 때문에 어떤 기능적 의미를 지니는 지는 대략 알 수 있다.
근데 보다 정확히 한 번 짚고 넘어가고 싶었다. 작동 방식을 뜯어보며 알아보자.
일단 첫 단계는 이동이다. 우리가 알고자 한 path=':movieId'
와 같은 path는 위에 보이는 search
와 같이 딱 고정된 route로 이동하는 게 아니다.
🚨주의:
path=":movieId"
에선/
라는 path가 생략되어 있다.
- Layout컴포넌트를 기반으로 모두 /를 base로 사용하고 있기 때문
parameter로 들어오는 값을 path의 동적 루트로 활용하는 것으로써,
그말인즉 사용할 컴포넌트는 동일할 지언정, 어떤 것이 들어오느냐에 따라 URL과 그에 따라 내용이 바뀐다는 것이다.
이러한 궁금증이 생긴 곳은 netflix 클론을 만들면서 작성된 코드로써, 이 프로젝트에선 axios를 통해 movieDB api의 데이터를 가져온다.
그리고 검색페이지에서 검색을 하게되면 검색 내용에 따라 영화목록이 만들어지는데, 이때 A라는 영화의 포스터를 클릭시 해당 A영화의 id값을 가져와 그 id값을 route path로 활용해 이동하는 것이다.
이때의
movie.id
는 목록을 작성할때 사용하는 api 데이터에 속해 있는 해닥 특정 영화의 고유 id값이다.
이렇게 이동한 path에서 가져오는 컴포넌트 페이지는 DetailPage이다.
그리고 이 페이지의 코드에선 다시 useParams
라는 hook을 통해 URL을 읽어 원하는 parameter값을 가져오고, 그 id에 맞는 데이터를 다시 axios를 통해 불러와 해당 영화의 이미지를 배경으로 적용한다.
useParams는 react-router-dom에서 제공하는 hook입니다.
만약 react-router-dom이 설치되어 있지 않다면 이것부터 설치하자.
npm install react-router-dom
그리고 나서 useParams를 import해 아래처럼 작성해주면 된다.
const { params명 } = useParams();
그리고 다시 저 변수를 사용할 때도 params명 그대로 사용해주면 된다.
말로만으로는 이해가 안 될 수 있으니 아래 예시를 보자.
App.js
function App () {
return (
// ...
<Route path="/" element={<Layout />} />
<Route path=":movieId" element={<DetailPage />} /> // parameter명 설정
// ...
)
}
DetailPage.jsx
const { movieId } = useParams(); // path의 :params명과 동일
const [movie, setMovie] = useState({});
useEffect(() => {
async function fetchData() {
const request = await axios.get(`/movie/${movieId}`); // axios에서 활용
setMovie(request.data);
}
fetchData();
}, [movieId]);
작성하는 방법은 간단하지만 유의할 점이 있다.
path의 parameter값을 담을 변수 명은 우리가 path를 지정할 때 사용할 이름과 일치시켜야 한다는 것이다.
예시 코드는 위에 사용법에서 작성해둔 예시 코드를 참고하면 된다.
실험삼아 다른 이름으로 작성이 되는지 실험해 봤는데, 작동하지 않았다.
log를 찍어봤을 때 undefined가 뜨고 결국 데이터를 불러오지 못한다.
가장 처음에 :movieId
와 search
는 동적 정적으로 다르다고 하였다.
그런데 그 이전에 근본적인 것도 다르다.
여기에서 movieId는 parameter이고 search는 pathname이라는 것이다.
때문에 useParams
를 통해서는 pathname을 구할 수 없다.
실험을 위해 path를 수정하고 다시 찍어보았다.
function App() {
return (
// ...
<Route path="/" element={<Layout />}>
<Route index element={<MainPage />} />
<Route path="detail/:movieId" element={<DetailPage />} /> // path 수정
<Route path="search" element={<SearchPage />} />
</Route>
// ...
);
}
코드와 함께 위 사진을 보면 알 수 있듯이 명확한 구분을 위해 path설정을 조금 바꿨다.
이전 예시들에선 기본 pathname없이 :movieId
를 사용했던 것에서, 지금은 detail
이란 pathname을 추가해주었다.
그리고 useParams에 담긴 값을 log로 찍어보면 위에서처럼 detail을 제외한 뒤의 movieId에 대한 값만 담긴다.
즉, useParams로는 pathname을 가져올 수 없다는 것이 확인 된 것.
그렇다면 pathname은 무엇으로 가져오느냐? 이때 사용하는 것은 useLocation
이다.
이에 대한 정리는 차후에 useNavigate
와 함께 할 예정이다. 일단은 useParams에 대한 유의점을 인지하도록 하자!
URL의 dynamic params 알아보기..
이상 끝-!
정리 감사합니다