React 애플리케이션을 개발할 때 여러 페이지를 관리해야 하는 상황이 발생합니다. 이때 사용하는 것이 라우팅(Routing)인데, React에서는 react-router-dom
라이브러리를 통해 라우팅을 구현할 수 있습니다.
특히, createBrowserRouter
는 React Router v6.4에서 도입된 새로운 API로, 라우터 객체를 생성하고 라우팅을 더욱 직관적이고 효율적으로 관리할 수 있게 해줍니다.
웹 애플리케이션을 개발할 때 여러 페이지가 존재하고, 이 페이지들 간의 이동이 필요합니다. 이를 관리하는 방법이 바로 '라우팅'입니다.
React에서는 react-router-dom
라이브러리를 통해 클라이언트 사이드 라우팅을 쉽게 구현할 수 있습니다. createBrowserRouter
는 이 라이브러리의 새로운 기능으로, 더 나은 데이터 로딩, 에러 처리, 중첩된 라우팅 등을 지원합니다.
이러한 기능들은 복잡한 애플리케이션을 더욱 효율적으로 관리할 수 있게 돕습니다.
createBrowserRouter
는 React Router v6.4에서 새롭게 도입된 라우터 생성 방식으로, 기존의 BrowserRouter
보다 더 많은 기능을 제공합니다.
이 함수는 라우터 객체를 선언적으로 생성할 수 있게 해주며, 라우터의 설정을 객체 형태로 관리할 수 있게 만듭니다. 이를 통해 라우팅을 설정하는 코드가 더 직관적이고 읽기 쉬워지며, 확장성도 높아집니다.
데이터 로딩
createBrowserRouter
는 라우트별로 미리 데이터를 로딩할 수 있는 기능을 제공합니다. 이를 통해 컴포넌트가 렌더링되기 전에 필요한 데이터를 불러오고, 로딩 상태를 자동으로 처리할 수 있습니다. 예를 들어, 서버에서 데이터를 가져와 페이지에 표시하는 작업을 라우팅 시점에서 처리할 수 있습니다.
에러 처리
각 라우트별로 에러 경계를 설정할 수 있어, 오류가 발생했을 때 표시할 UI를 손쉽게 정의할 수 있습니다. 예외 처리를 라우터 레벨에서 처리함으로써 애플리케이션의 안정성을 높일 수 있습니다.
타입 안정성
TypeScript와 함께 사용할 때 createBrowserRouter
는 더 나은 타입 추론을 제공하여, 코드 작성 시 타입 오류를 줄이고 안정성을 높여줍니다.
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
import Home from './pages/Home';
import About from './pages/About';
import ErrorPage from './pages/ErrorPage';
const router = createBrowserRouter([
{
path: "/",
element: <Home />,
errorElement: <ErrorPage />, // 오류 발생 시 표시할 컴포넌트
},
{
path: "/about",
element: <About />,
loader: async () => {
const response = await fetch('/api/about-data');
return response.json(); // 데이터 로더에서 받은 데이터 반환
},
}
]);
function App() {
return <RouterProvider router={router} />; // 라우터 객체를 RouterProvider에 전달
}
위 코드에서 createBrowserRouter
를 사용하여 라우팅을 설정하고, 각 라우트에서 데이터를 로딩하거나 에러 처리를 할 수 있는 방법을 설정했습니다.
데이터 로더는 라우트가 활성화되기 전에 데이터를 가져오는 데 사용됩니다. useLoaderData
훅을 활용하여 데이터에 접근할 수 있습니다.
import { useLoaderData } from 'react-router-dom';
function About() {
const data = useLoaderData(); // useLoaderData 훅을 사용하여 데이터 가져오기
return (
<div>
<h1>About Page</h1>
{/* 로더에서 불러온 데이터 표시 */}
</div>
);
}
이 코드에서는 useLoaderData
훅을 사용하여, About
페이지가 렌더링되기 전에 loader
에서 불러온 데이터를 표시합니다.
라우팅 시 로딩 상태를 UI에 반영할 수 있습니다.
tsx
복사편집
import { useNavigation, Outlet } from 'react-router-dom';
function Layout() {
const navigation = useNavigation();
return (
<div>
{navigation.state === 'loading' && <LoadingSpinner />}
<Outlet />
</div>
);
}
action
을 사용한 폼 데이터 처리action
은 라우트에서 사용자가 제출한 데이터를 처리하는 데 사용됩니다. 예를 들어, 사용자가 폼을 제출했을 때 데이터를 서버로 전송하거나, 폼 데이터를 처리할 수 있습니다.
import { json, redirect } from 'react-router-dom';
async function postData({ request }) {
const formData = new URLSearchParams(await request.text());
const name = formData.get('name');
// 서버에 데이터 전송
const response = await fetch('/api/submit', {
method: 'POST',
body: JSON.stringify({ name }),
});
// 성공 시 리디렉션
if (response.ok) {
return redirect('/thank-you');
} else {
return json({ error: '서버에 문제가 발생했습니다.' });
}
}
const router = createBrowserRouter([
{
path: "/form",
element: <Form />,
action: postData, // action을 사용하여 폼 데이터를 처리
},
]);
위 코드에서는 action
을 사용하여 폼 데이터를 처리하고, 성공 시 리디렉션을 합니다. request
객체에서 데이터를 추출하고, 서버로 전송한 후 응답에 따라 리디렉션을 하거나 오류 메시지를 반환합니다.
React Router에서 에러 처리는 매우 중요합니다. 사용자가 잘못된 URL에 접근하거나, 데이터 로딩 중 오류가 발생할 때 적절한 에러 화면을 보여주는 것이 중요합니다.
createBrowserRouter
에서는 errorElement
를 사용하여 라우트별 에러 화면을 설정할 수 있습니다.
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
import ErrorPage from './pages/ErrorPage';
const router = createBrowserRouter([
{
path: "/",
element: <Home />,
errorElement: <ErrorPage /> // 해당 라우트에서 발생한 오류를 처리할 에러 페이지
},
// 다른 라우트 설정...
]);
function App() {
return <RouterProvider router={router} />;
}
위 코드에서 각 라우트는 errorElement
를 통해 에러가 발생했을 때 표시할 UI를 정의합니다. 예를 들어, Home
페이지에서 오류가 발생하면 ErrorPage
컴포넌트가 표시됩니다.
서버에서 데이터를 불러오는 과정에서 오류가 발생하는 경우, loader
에서 반환된 데이터가 실패하면 에러 페이지를 자동으로 표시할 수 있습니다.
또한, 폼 데이터 처리 시 오류가 발생하면 action
에서 에러 메시지를 반환하여 사용자에게 알릴 수 있습니다.
React Router는 중첩된 라우트를 지원하여, 하나의 페이지에서 여러 개의 서브 페이지를 관리할 수 있습니다.
중첩 경로를 사용하면, 하나의 부모 라우트에 하위 라우트를 포함시킬 수 있으며, 부모 라우트의 UI와 함께 하위 라우트의 UI를 렌더링할 수 있습니다.
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
import Home from './pages/Home';
import Profile from './pages/Profile';
import ProfileDetails from './pages/ProfileDetails';
const router = createBrowserRouter([
{
path: "/",
element: <Home />,
children: [
{
path: "profile",
element: <Profile />,
children: [
{
path: ":id",
element: <ProfileDetails />,
}
]
}
]
}
]);
function App() {
return <RouterProvider router={router} />;
}
위 코드에서는 Home
페이지가 부모 라우트로 설정되고, 그 안에 Profile
페이지가 중첩된 라우트로 설정됩니다. 또한, Profile
페이지 안에 ProfileDetails
페이지가 추가로 설정되어 :id
파라미터를 사용하여 세부 페이지를 렌더링합니다.
Outlet
사용중첩된 라우트에서는 부모 컴포넌트에서 Outlet
을 사용하여 하위 라우트의 콘텐츠를 렌더링할 수 있습니다.
import { Outlet } from 'react-router-dom';
function Profile() {
return (
<div>
<h1>Profile Page</h1>
<Outlet /> {/* 여기에 하위 라우트가 렌더링됩니다 */}
</div>
);
}
위의 Profile
컴포넌트에서는 Outlet
을 사용해 하위 라우트를 렌더링합니다. 이렇게 하면 Profile
페이지가 렌더링된 후, 해당 페이지에 맞는 하위 라우트가 표시됩니다.
React Router의 createBrowserRouter
는 라우팅을 더욱 직관적이고 효율적으로 관리할 수 있는 강력한 도구입니다. 데이터 로딩, 에러 처리, 중첩된 라우트 설정 등을 라우터 수준에서 처리할 수 있기 때문에, 애플리케이션의 코드 구조가 깔끔하고 유지보수하기 쉬워집니다. 또한, 타입 안정성과 함께 제공되어 개발 과정에서 발생할 수 있는 오류를 미리 방지할 수 있습니다.
createBrowserRouter
와 useLoaderData
, action
, errorElement
, 그리고 중첩 라우트를 적극적으로 활용하면 복잡한 애플리케이션에서도 라우팅을 깔끔하게 처리할 수 있습니다.
https://www.dhiwise.com/post/the-power-of-createbrowserrouter-optimizing-your-react-app