다이내믹(동적) 라우팅

서버로부터 응답 받은 데이터를 리스트 렌더링 한 후, 각 아이템을 통해 이동되는 페이지를 동적으로 라우팅하도록 설정해봅니다. 응받 받은 데이터가 가진 ID 파라미터 값에 따라 다이내믹(dynamic) 하게 라우팅 되어야 합니다.

ezgif.com-gif-maker.gif

경로(path)가 동적으로 변경될 경우 아래와 같이 설정합니다.

<Main>
	<Routes>
		<Route path="/" element={<Landing />} />
		<Route path="/dashboard" element={<Dashboard />} />
		**<Route path="/products" element={<Products />} />
		<Route path="/product/:id" element={<ProductDetail />} />**
	</Routes>
</Main>

JavaScript 객체로 라우트를 구성했다면 다음과 같이 작성합니다.

const routeElements = useRoutes([
  { path: '/', element: <Landing /> },
  { path: '/dashboard', element: <Dashboard /> },
  { path: '/products', element: <Products />,
  **{ path: '/product/:id', element: <ProductDetail /> },**
]);

참고

React Router

Route 컴포넌트 (동적 라우팅 설정)

Link 컴포넌트를 통해 라우트 링크를 설정할 경우, to prop에 ID 파라미터를 동적으로 설정합니다.

src/pages/Products/Products.js

import styles from './Products.module.css';
import { useEffect, useState } from 'react';
import { Helmet } from 'react-helmet-async';
**import { Link } from 'react-router-dom';**
import { Spinner, WireframeBox } from 'components';
import { classNames } from 'utils';
import { hangleVowels } from 'services'

export default function Products(props) {

  const [vowels, setVowels] = useState(null);

  useEffect(() => {
		
		let mounted = true;

    hangleVowels.getVowelAll().then(json => {
      mounted && setVowels(json);
    });

		return () => {
			mounted = false;
		};

  }, []);

  return (
    <>
      <Helmet>
        <title>프로덕트 ⌁ {process.env.REACT_APP_TITLE}</title>
      </Helmet>
      <div className={classNames('page')(styles.products)} {...props}>
        <h2 tabIndex={0} className={styles.headline}>
          프로덕트
        </h2>
        {!vowels ? (
          <Spinner />
        ) : (
          <WireframeBox className={styles.grid} style={{ height: null }}>
            {vowels.map(vowel => (
              <WireframeBox key={vowel.id}>
                **<Link className={styles.link} to={`/product/${vowel.id}`}>
                  {vowel.letter}
                </Link>**
              </WireframeBox>
            ))}
          </WireframeBox>
        )}
      </div>
    </>
  );
}