일반적인 라우팅 경로에 path parameter 를 적용해서 마치 매개변수처럼 사용하는 방법입니다.
예를 들어서 /detail
이라는 라우팅 경로에 :id
를 붙히게되면
/detail:id
에서 id
라는 값이 변수처럼 활용되는 것입니다.
Monsters Component => 최상위 컴포넌트
function Monsters() { const [monsters, setMonsters] = useState([]); useEffect(() => { fetch("https://jsonplaceholder.typicode.com/users") .then((res) => res.json()) .then((res) => setMonsters(res)); }, []); return ( <div className="monsters"> <h1>Assignment - Dynamic Routing</h1> <CardList monsters={monsters} /> </div> ); }
먼저 최상위 컴포넌트에서 하위 컴포넌트인 CardList 에
fetch 로 받아온 데이터를 props 로 넘겨줍니다.
CardList Component
function CardList({ monsters }) { return ( <div className="cardList"> {monsters.map(({ id, name, email }) => { return <Card key={id} id={id} name={name} email={email} />; })} </div> ); }
Monsters Component 에서 Props 로 내려받은 fetch data 를 이용해서
하위 컴포넌트인 Card Component 를 map 메서드로 맵핑하며
각 key 에 해당하는 정보를 쪼개어 props 로 넘겨줍니다.
Card Component
function Card({ id, name, email }) { const navigate = useNavigate(); const linkMonster = () => { navigate(`/detail/${id}`); }; return ( <div className="card" onClick={linkMonster}> <img src={`https://robohash.org/${id}?set=set2&size=180x180`} alt="user avatar" /> <h2>{name}</h2> <p>{email}</p> </div> ); }
CardList Component 에서 props 로 받은 데이터중 ID 값을 통해서
동적 라우팅을 구현합니다.
동적 라우팅 구현을 위해서 useNavigate
를 사용해줍니다.
카드 리스트중 특정 카드를 클릭하면 /detail/{해당 카드의 ID}
링크로 라우팅되는 방식입니다.
Monster Component => 상세 페이지
function Monster() { const [monster, setMonster] = useState({}); const params = useParams(); const monsterID = params.id; const navigate = useNavigate(); useEffect(() => { fetch("https://jsonplaceholder.typicode.com/users") .then((res) => res.json()) .then((res) => { setMonster(res[monsterID - 1]); }); }, [monsterID]); return ( <article className="monster"> <div className="btnWrapper"> <button onClick={() => { navigate("/"); }} Back to Monsters List </button> </div> <Card id={monster.id} name={monster.name} email={monster.email} /> <div className="btnWrapper"> <button onClick={() => { navigate( `/detail/${monsterID === "1" ? "1" : Number(monsterID) - 1}` ); }} Previous </button> <button onClick={() => { navigate( `/detail/${monsterID === "10" ? "10" : Number(monsterID) + 1}` ); }} Next </button> </div> </article> ); }
Monster Component 의 라우팅 주소는
<Route path="/detail/:id" element={<Monster />} />
위와 같이 path parameter 를 이용해서 지정되어있습니다.
CardList 의 Card 를 클릭해서 상세 페이지(Monster)로 라우팅되는 방식입니다.
그럼 하나의 Monster Component에서 달라지는 path parameter마다
다른 정보를 보여주는 방법은 뭘까요?
useParams Hook
을 이용하면 가능합니다.
Route.js 에서 path parameter 를 :id
로 지정했기 때문에
const params = useParams();
const monsterID = params.id;
해당 코드에 의해서 MonsterID
는 /detail/1
링크로 라우팅됐다면 1이 됩니다.
이제 라우팅되는 주소의 path parameter Value 를 알게됐습니다.
이 정보를 이용해서 다시금 fetch 로 정보를 받아와서
setMonster(res[monsterID - 1]);
위와 같이 MonsterID
에 해당하는 정보를 필터링하고
필터링된 데이터를 이용해서
Card Component 를 렌더링합니다.
한정된 정보를 다루는 페이지는 각 페이지마다 Route 주소를 다르게 주면 될 일이지만
예를 들어서 블로그 포스팅을 다루는 페이지라고 했을 때,
포스팅된 글의 갯수가 1개가 될 수도, 100개 , 10000개가 될 수도 있기 떄문에
각각의 Route 주소를 전부 설정하면 매우 비효율적인 코드가 될 것입니다.
앞으로 만들게될 페이지가 어떤 페이지가 될지는 알 수 없지만
동적 라우팅 개념을 알게된 지금 이후로는
해당 기법이 어울리는 페이지인지 아닌지 적재적소에 판단하고 적용해보도록 해야겠습니다.