REACT - 동적 라우팅

SeungMin·2022년 8월 21일
0

WECODE

목록 보기
12/19

동적 라우팅

일반적인 라우팅 경로에 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 를 이용해서 지정되어있습니다.

CardListCard 를 클릭해서 상세 페이지(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 주소를 전부 설정하면 매우 비효율적인 코드가 될 것입니다.

앞으로 만들게될 페이지가 어떤 페이지가 될지는 알 수 없지만
동적 라우팅 개념을 알게된 지금 이후로는

해당 기법이 어울리는 페이지인지 아닌지 적재적소에 판단하고 적용해보도록 해야겠습니다.

profile
공부기록

0개의 댓글