BrowserRouter vs createBrowserRouter

white noise·2025년 11월 25일

react-router-dom을 사용해서 라우팅을 구현하려고 할 때, 대표적으로 두 가지 방법이 있다.

BrowserRouter을 사용하는 방식과, createBrowserRouter을 사용하는 방식이 있다.

이번 포스트에서는 이 둘의 차이점과 어떤 걸 사용해야 좋을지 알아보자.

BrowserRouter

BrowserRouter 방식은 초기 React Router부터 사용된 방식이다.

import React from "react";
import ReactDOM from "react-dom/client";
import { BrowserRouter, Routes, Route } from "react-router";
import App from "./app";

const root = document.getElementById("root");

ReactDOM.createRoot(root).render(
  <BrowserRouter>
    <Routes>
      <Route path="/" element={<App />} />
    </Routes>
  </BrowserRouter>,
);

이런식으로 <BrowserRouter><Routes>로 감싸주어야 라우팅이 가능하다.

렌더할 때는 어플리케이션을 <BrowserRouter>로 감싸주면 된다.

import React from "react";
import ReactDOM from "react-dom/client";
import { BrowserRouter } from "react-router";
import App from "./app";

const root = document.getElementById("root");

ReactDOM.createRoot(root).render(
  <BrowserRouter>
    <App />
  </BrowserRouter>,
);

이런식으로 경로를 중첩시키는 것도 가능하다.

<Routes>
  <Route path="dashboard" element={<Dashboard />}>
    <Route index element={<Home />} />
    <Route path="settings" element={<Settings />} />
  </Route>
</Routes>

"dashboard/settings"

createBrowserRouter

createBrowserRouter는 비교적 최신 방법이다. React Router v6.4에서 도입됐다.

차이점으로는 라우트 정의를 컴포넌트가 아닌 자바스크립트 객체로 분리하여 생성한다.

추가 기능으로

  • Data APIs: loader(렌더링 전 데이터 로딩), action(폼 제출 처리)
  • 에러 처리: errorElement를 지정해서 NotFound 페이지를 처리할 수 있다.
import { createBrowserRouter } from "react-router";

function Root() {
  return <h1>Hello world</h1>;
}

const router = createBrowserRouter([
  { path: "/", Component: Root },
]);

이런식으로 createBrowserRouter을 사용할 수 있고,
라우팅은 아래처럼 하면 된다.

createBrowserRouter([
  {
    path: "/",
    Component: Root,
    children: [
      { index: true, Component: Home },
      { path: "about", Component: About },
      {
        path: "auth",
        Component: AuthLayout,
        children: [
          { path: "login", Component: Login },
          { path: "register", Component: Register },
        ],
      },
      {
        path: "concerts",
        children: [
          { index: true, Component: ConcertsHome },
          { path: ":city", Component: ConcertsCity },
          { path: "trending", Component: ConcertsTrending },
        ],
      },
    ],
  },
]);

children을 이용해서 중첩 라우팅도 할 수 있다.

렌더할 때는 RouterProviderrouter를 전달해주면 된다.

import React from "react";
import ReactDOM from "react-dom/client";
import { createBrowserRouter } from "react-router";
import { RouterProvider } from "react-router/dom";

const router = createBrowserRouter([
  {
    path: "/",
    element: <div>Hello World</div>,
  },
]);

const root = document.getElementById("root");

ReactDOM.createRoot(root).render(
  <RouterProvider router={router} />,
);

위에서 말한 것 처럼 data loading이나 actions를 사용할 수 있다. 아래는 loader에 대한 예제다

import {
  createBrowserRouter,
  useLoaderData,
} from "react-router";

createBrowserRouter([
  {
    path: "/teams/:teamId",
    loader: async ({ params }) => {
      let team = await fetchTeam(params.teamId);
      return { name: team.name };
    },
    Component: Team,
  },
]);

function Team() {
  let data = useLoaderData();
  return <h1>{data.name}</h1>;
}

정리

그러면 어떤 걸 써야 할까?

createBrowserRouter을 사용하는 게 좋다.
사실 v6.4 이전부터 사용하고 있었던 BrowserRouter을 지원해주는 것이지, 공식문서에서도 createBrowserRouter을 권장하고 있다.

데이터 로딩과, 액션과 같은 추가 기능 뿐만 아니라, 객체로 관리하기 때문에, 복잡한 라우팅을 쉽게 관리할 수 있다.
그리고 라우팅 중 오류가 생겼을 때도 errorElement를 이용해 쉽게 에러 처리를 할 수 있다.

마무리

사실 공식문서에는 이 두가지 외에도 프레임워크 모드라는 새로운 방식도 소개하고 있다.

  • Next.js, Solid Start ... 등을 고려중일 때
  • SSR을 할지 말지 고민중일 때 (SPA, SSR, 동적 렌더링 모두 가능)
  • Next.js에서 React Router로 마이그레이션 하려는 경우

와 같은 상황이 있을 때 프레임워크 모드를 사용하라고 하기도 한다..

각자 상황에 맞는 걸 알맞게 사용하면 될듯 하다..
다만 이번 블로그의 주제에 맞게 말하자면, BrowserRouter을 사용하기 보다는 createBrowserRouter을 사용해보는 건 어떨까?

출처

https://reactrouter.com/home

profile
Hello World

0개의 댓글