[React] 동적 라우팅으로 상세페이지 연결하기

sujin·2022년 10월 2일
4

React

목록 보기
12/17
post-thumbnail
post-custom-banner

1. 동적 라우팅의 정의와 필요성

라우팅의 가장 기본적인 방법은 정적 라우팅이다. 하지만, 복잡하고 규모가 큰 프로젝트 진행시 경로를 미리 설정하는 방식만으로는 처리하기 힘들다.

예를 들어 100개의 리스트들이 있다고 가정했을 때, 정적 라우팅을 사용한다면, 각각의 리스트에 대한 상세 페이지 경로를 설정해 주어야 할 것이다.

import React from 'react';
import { BrowserRouter, Route, Routes } from 'react-router-dom';

const Router = () => {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<ListComponent />} />
        <Route path="/post/1" element={<FirstPosting />} />
        <Route path="/post/2" element={<SecondPosting />} />
				...
      </Routes>
    </BrowserRouter>
  );
};

export default Router;

따라서, 이런 문제를 해결하기 위해 나온 개념이 동적 라우팅 이다.

동적 라우팅

Route 설정 시, URL 전체 형태를 미리 정하는 것이 아니라 특정 규칙을 정의한 후 규칙에 부합하는 URL이 있을 경우 해당하는 element를 보여주게 설정하는 것이다.


2. react-router-dom을 이용한 동적 라우팅 구현

<Route path="/post/:문자열" element={<Detail />}>
  • Route 컴포넌트의 path prop에 :기호를 활용한다.
  • 경로/:문자열 형태로 path를 설정하면 URL에서 경로/뒤에 무슨 글자가 오든 이 Route로 연결되게 된다.
  • 하지만, 위와 같이 설정을 해주면 어떤 URL로 들어가도 똑같은 내용의 상세페이지만 보여 줄 수 있다. /post/1 로 접속하면 1번 포스팅의 내용을 /post/2 로 접속하면 2번 포스팅의 내용을 보여 줘야한다.
  • 이때, 유용하여 사용되는 것이 path parameter이다.

3. 동적 라우팅과 Path Parameter

<Route path="/post/:id" element={<DetailPageComponent />}
  • path parameter는 URL에 있는 값을 마치 매개변수(parameter)처럼 사용한다. 이를 통해 큰 틀은 동일 하되 다른 UI를 보여 줄 수 있도록 처리한다.
  • 동적 라우팅을 설정할 때 Route의 path prop에 경로/문자열 을 넣어야 한다고 했는데 이때 문자열 자리에 작성되는 것이 path parameter의 이름이다. path parameter의 이름은 자유롭게 지을 수 있으며, 위의 경우에는 id 가 이름이 된다.

4. path parameter의 활용

useParams hook

  • path parameter의 값을 편하게 가져올 수 있다.
  • path parameter의 값이 바뀌면 컴포넌트를 리렌더링 해주는 기능을 제공한다.
import { useParams } from 'react-router-dom';

const params = useParams();
  • useParams hook을 호출하면 path params의 값을 객체 형태로 반환해 준다.
    • key 는 Route에서 설정한 path parameter의 이름
    • valuepath parameter의 실제로 전달 된 값
  • 아까 위에서 path paramter의 이름을 id로 지정했기 때문에 post/1으로 접속한다면 useParams hook의 return값은 {id :1}이 되는 것이다.

5. 리스트와 상세페이지 예시

위에서 배운 내용을 예시를 통해 간단히 정리해 보도록 하자. 사용자의 정보를 보여주는 리스트 페이지와 한 명의 사용자에 대한 상세 정보를 보여주는 상세 페이지를 만들어 보도록 하겠다.

동적 라우팅을 사용한 경로 지정

// Router.js

import { BrowserRouter, Routes, Route } from 'react-router-dom';
import List from './pages/List';
import Detail from './pages/Detail';

const App = () => {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<List />} />
        <Route path="/detail/:id" element={<Detail />} />
      </Routes>
    </BrowserRouter>
  );
};

export default App;


리스트 컴포넌트

// List.js

import React, { useState, useEffect } from 'react';
import { Link } from 'react-router-dom';

const List = () => {
  const [users, setUsers] = useState([]);

  useEffect(() => {
    fetch('https://reqres.in/api/users')
      .then((response) => response.json())
      .then((result) => setUsers(result.data));
  }, []);

  return (
    <section>
      <nav>
        {users.map(({ id, first_name, email, avatar }) => (
          <Link key={id} to={`/detail/${id}`}>
            <p>
              <strong>{first_name}</strong>
            </p>
            <p>{email}</p>
            <img alt="avatar" src={avatar} />
          </Link>
        ))}
      </nav>
    </section>
  );
};

export default List;
  • List.js 는 전체 사용자 리스트를 보여준다. 사용자 정보는 실제 API 호출을 하기 위해 https://reqres.in/ 에서 제공해주는 샘플 API를 활용했다.
  • 동작 로직은 리스트에서 특정 사용자를 클릭하면 사용자의 상세 페이지로 이동하도록 Link 컴포넌트를 사용했다. Link 컴포넌트의 to prop에 /detail 로 이동시키되, 뒤에 현재 클릭한 사용자의 idpath parameter로 담아서 이동 시킨다.

상세 컴포넌트

// Detail.js

import React, { useState, useEffect } from 'react';
import { useParams } from 'react-router-dom';

const Detail = () => {
  const params = useParams(); // 1
  const userId = params.id; // 2

  const [user, setUser] = useState({});

  useEffect(() => {
    fetch(`https://reqres.in/api/users/${userId}`) // 3
      .then((response) => response.json())
      .then((result) => setUser(result.data));
  }, [userId]); // 4

  const { first_name, email, avatar } = user;

  return (
    <section>
      <article>
        <p>
          <strong>{first_name}</strong>
        </p>
        <p>{email}</p>
        <img alt="avatar" src={avatar} />
      </article>
    </section>
  );
};

export default Detail;
  • 먼저 useParams hook을 이용해서 params 객체를 가져온다. const params = useParams();
  • params 객체 안에서 id프로퍼티의 value를 userId 변수에 할당한다. const userId = params.id;
  • useEffect안에 API를 호출하고, userId값을 활용하여 동적으로 API URL을 설정한다. 그리고 userId의 값이 변경 될때마다 새로운 user의 정보를 보여줘야하기 때문에 useEffect 의존성 배열에 [userId]를 포함 시켜둔다.

profile
개발댕발
post-custom-banner

0개의 댓글