[React]동적라우팅과 Path Parameter

hyeonze·2022년 1월 14일
0

Path Parameter란

localhost:3000/product/2
localhost:3000/product/45
localhost:3000/product/125

url 경로에서 달라지는 부분을 저장하는 매개 변수
위의 코드에서 2, 45, 125에 해당

Route컴포넌트에서 Path Parameter 정의하기

<BrowserRouter>
  <Routes>
    <Route path='/product/:id' element={<ProductDetail />} />
  </Routes>
</BrowserRouter>
  • : 는 Path Parameter 가 올 것임을 의미
  • id 는 해당 Path Parameter 의 이름을 의미. 변수 명을 짓듯이, 임의의 이름 지정가능. ex) :productId

Path Parameter 루틴


1. 카드를 클릭하면, onClick 이벤트시 발생하는 navigate 함수를 통해 /product/1 로 이동. URL 이 /product/1 로 변하면, Router 컴포넌트에 정의되어 있는 path='/product/:id' 에 따라, ProductDetail 컴포넌트가 마운트.
2. ProductDetail 컴포넌트에서는 백엔드에 id 가 1 인 아이템에 대한 정보를 요청.
3. 응답으로 받은 정보를 setData 함수를 통해 data 라는 state에 저장하고, 이를 통해 상세 페이지 UI 가 그려짐.

의문 : id값이 url에 존재하는데 어떻게 ProductDetail컴포넌트로 가져오는가?
해답 : useParams Hook 사용

useNavigate, useLocation, useParams Hook

요약

useNavigate : url 를 변경하는 함수 를 반환
useLocation : 현재 경로 정보를 담고 있는 객체 를 반환
useParams : Router 에 등록해준 path parameter 정보를 담고 있는 객체 를 반환

useNavigate

function Product(props) {
  const navigate = useNavigate();

  const goToDetail = () => {
    navigate(`/product/${props.id}`);**
  }
  
  return (
    <div className="productContainer" onClick={goToDetail}>
      ...
    </div>
  )
}

useNavigate 훅을 실행하면 페이지를 이동시키는(url을 변경시키는) 함수를 반환. 위 예제 코드에서 해당 함수를 navigate 라는 변수에 할당했음. 따라서, navigate()와 같은 방식으로 함수를 호출가능.

navigate() 함수의 인자에 이동하고자 하는 url(ex. /products)을 전달하면, 해당 url로 화면을 이동.

navigate('/product/1'); // '/product/1' 로 이동

정수값을 인자로 받아 앞뒤 경로로 이동 가능.

navigate(-1); // 뒤로 가기
navigate(-2); // 뒤로 2페이지 가기
navigate(1);  // 앞으로 가기

자세한 내용은 공식문서로

useLocation

function ProductDetail(props) {
  const location = useLocation();

  console.log(location);
  
  return (
    ...
  )
}

// console
{
  pathname: '/product/1', 
  search: '', 
  hash: '', 
  state: null, 
  key: 'default'
}

useLocation 훅을 실행하면 경로 정보를 담고 있는 객체 를 반환.

  • pathname: 현재 경로 값
  • search: 현재 경로의 query parameter 값

useParams

// 현재경로: /product/1

function ProductDetail(props) {
  const params = useParams();
  
  console.log(params);

  return (
    ...
  )
}

//console
{
  id: 1
}

useParams 훅을 실행하면 path parameter 정보를 담고 있는 객체 를 반환. 키네임은 Router에서 :id와 같이지정해줬던 값. productId, itemId, monsterId 등 구체화해서 지정.

// Router.js
<BrowserRouter>
  <Routes>
    <Route path='/product/:id' element={<ProductDetail />} />
  </Routes>
</BrowserRouter>

useParams 활용한 동적라우팅

// ProductDetail.js
// current url -> localhost:3000/product/1

function ProductDetail() {
  const [data, setData] = useState();
  const params = useParams();

  console.log(params.id) // 1
  
  useEffect(() => {
  fetch(`${API}/${params.id}`)
    .then(res => res.json())
    .then(res => setData(res));
},[]);

  return (
    ...
  );	
}

정리

  • 리스트 페이지의 개별 상품을 클릭
    navigate("/product/1") 로 상세 페이지로 이동
  • 상세 페이지로 이동하면 url은 "http://localhost:3000/product/1" 과 같이 변경됨
  • 페이지에 필요한 데이터를 useEffect 에서 fetching
    • 필요한 id는 URL에 존재하므로 useParams().id 에서 가져옴
    • 해당 id를 가지고 백엔드에서 만들어준 API를 호출
function ProductDetail() {
  const params = useParams();
  
  useEffect(() => {
    const productId = params.id;
    fetch(`http://123.456.789:8000/products/${productId}`) // 1
      .then(res => res.json())
      .then(res => setData(res));
  },[]);

  return (
    ...
  )
}
  • 서버에서 가져온 데이터(res)를 컴포넌트의 data state 에 저장
  • state 에 담긴 데이터로 컴포넌트 UI 를 render

활용

이전상품/이후상품 이동버튼 제작 시, Path Parameter로 url변경 후, params.id를 useEffect의 의존성배열에 담아 url변경에 따른 디테일 페이지 변경을 구현
주의할점 : useParams()의 리턴값의 객체의 값들은 문자열 형태임. 뒷 페이지로 이동시 Number(params.id)를 통해 숫자로 변형한 후 조작해줘야 함.

React Router 공식문서

profile
Advanced thinking should be put into advanced code.

0개의 댓글