본문 바로가기
React

React에서 커스텀 라우터 구현하기

by 굿센스굿 2024. 12. 17.
반응형

React에서 라우팅은 일반적으로 React Router와 같은 라이브러리를 사용해 간단하게 구현됩니다. 하지만 커스텀 라우터를 구현하면 애플리케이션에 더 높은 수준의 제어권을 가질 수 있습니다. 이번 글에서는 커스텀 라우터를 React로 구현하는 방법과 활용 사례를 소개합니다.


라우터란?

라우터는 URL과 애플리케이션의 화면을 연결하는 역할을 합니다. 사용자가 특정 URL에 접근하면, 해당 URL에 매핑된 컴포넌트가 렌더링됩니다. React에서 라우터는 SPA(Single Page Application)의 핵심 기능으로, 페이지 전환 없이 다양한 화면을 동적으로 렌더링할 수 있게 해줍니다.


커스텀 라우터의 필요성

기본적으로 React Router와 같은 라이브러리는 강력하고 유연하지만, 모든 애플리케이션이 이를 필요로 하지는 않습니다. 커스텀 라우터는 다음과 같은 경우 유용할 수 있습니다:

  1. 의존성 최소화: 외부 라이브러리에 의존하지 않고 라우팅 기능을 구축하고자 할 때.
  2. 간단한 요구사항: 간단한 라우팅만 필요한 경우.
  3. 특정 기능 구현: 라이브러리가 지원하지 않는 독특한 라우팅 동작이 필요한 경우.

커스텀 라우터 구현하기

React에서 커스텀 라우터를 구현하려면, URL 상태를 관리하고 해당 URL에 따라 컴포넌트를 렌더링하는 메커니즘을 만들어야 합니다.

1. 기본 구조 설계

React의 상태와 window.location 객체를 활용해 간단한 라우터를 구현할 수 있습니다.

import React, { useState, useEffect } from 'react';

const Router = ({ routes }) => {
  const [currentPath, setCurrentPath] = useState(window.location.pathname);

  useEffect(() => {
    const onLocationChange = () => {
      setCurrentPath(window.location.pathname);
    };

    window.addEventListener('popstate', onLocationChange);
    return () => window.removeEventListener('popstate', onLocationChange);
  }, []);

  const Component = routes[currentPath] || routes['/not-found'];

  return Component ? <Component /> : null;
};

export default Router;

2. 라우팅 링크 컴포넌트

라우팅 링크를 구현하려면 history.pushState를 사용하여 URL을 변경하고 상태를 업데이트해야 합니다:

const Link = ({ to, children }) => {
  const handleClick = (e) => {
    e.preventDefault();
    window.history.pushState(null, '', to);
    const popStateEvent = new PopStateEvent('popstate');
    window.dispatchEvent(popStateEvent);
  };

  return (
    <a href={to} onClick={handleClick}>
      {children}
    </a>
  );
};

export default Link;

3. 예제 애플리케이션

위에서 만든 RouterLink를 활용해 간단한 SPA를 구현해봅니다:

import React from 'react';
import Router from './Router';
import Link from './Link';

const Home = () => <h1>Home Page</h1>;
const About = () => <h1>About Page</h1>;
const NotFound = () => <h1>404 - Page Not Found</h1>;

const routes = {
  '/': Home,
  '/about': About,
  '/not-found': NotFound,
};

const App = () => (
  <div>
    <nav>
      <Link to="/">Home</Link>
      <Link to="/about">About</Link>
    </nav>
    <Router routes={routes} />
  </div>
);

export default App;

커스텀 라우터의 확장

위의 기본 커스텀 라우터는 간단하지만, 몇 가지 기능을 추가해 더 강력하게 만들 수 있습니다.

1. 동적 라우팅

URL에 동적 매개변수를 포함하려면 정규식을 사용하여 URL을 매칭하는 로직을 추가할 수 있습니다:

const matchRoute = (routes, path) => {
  for (const route in routes) {
    const paramNames = [];
    const regex = new RegExp(
      `^${route.replace(/:([^/]+)/g, (_, paramName) => {
        paramNames.push(paramName);
        return '([^/]+)';
      })}$`
    );

    const match = path.match(regex);
    if (match) {
      const params = paramNames.reduce((acc, paramName, i) => {
        acc[paramName] = match[i + 1];
        return acc;
      }, {});
      return { component: routes[route], params };
    }
  }
  return null;
};

2. 전역 상태와 통합

React Context를 사용하여 라우팅 상태를 전역적으로 관리할 수도 있습니다:

import React, { createContext, useContext, useState } from 'react';

const RouterContext = createContext();

export const RouterProvider = ({ children, routes }) => {
  const [currentPath, setCurrentPath] = useState(window.location.pathname);

  const navigate = (to) => {
    window.history.pushState(null, '', to);
    setCurrentPath(to);
  };

  const Component = routes[currentPath] || routes['/not-found'];

  return (
    <RouterContext.Provider value={{ navigate }}>
      {Component ? <Component /> : null}
      {children}
    </RouterContext.Provider>
  );
};

export const useRouter = () => useContext(RouterContext);

결론

React에서 커스텀 라우터를 구현하면 애플리케이션의 라우팅 로직을 완전히 제어할 수 있습니다. 간단한 라우팅 요구사항부터 동적 라우팅과 전역 상태 관리까지 다양한 요구를 충족할 수 있습니다. 커스텀 라우터를 통해 React의 SPA 기능을 더욱 심층적으로 이해하고, 필요한 경우 이를 확장해보세요.

반응형