React Router는 React 애플리케이션에서 навіга션을 만드는 필수 도구이며, 최신 버전에서는 새로운 기능과 성능 향상으로 개발자 경험을 지속적으로 개선하고 있습니다. 버전 7(또는 다른 미래 버전)에서 React Router는 巢형 라우트와 레이아웃 라우트와 같은 고급 기능을 제공하여 견고하고 효율적인 웹 애플리케이션을 구축하는 데 도움을 줍니다.
React Router 7(또는 최신 버전)의 주요 새로운 기능
최신 버전에서 소개된 중요한 개선 사항과 기능을 몇 가지 소개합니다:
1. 데이터 API를 사용한 간소화된 라우트 정의
새로운 데이터 API, 예를 들어 loader
와 action
은 라우트 내에서 더 선언적이게 데이터를 가져오고 수정할 수 있게 합니다.
이전 버전에서는 데이터 가져오기가 일반적으로 React 컴포넌트 내에서 useEffect
또는 클래스 컴포넌트의 라이프사이클 메서드를 사용하여 처리되었으며, 이는 데이터 가져오기 로직이 UI 렌더링과 혼합되어 복잡해질 수 있었습니다.
React Router v5 예제
import { useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';
function UserPage() {
const { id } = useParams();
const [userData, setUserData] = useState(null);
useEffect(() => {
fetch(`/api/users/${id}`)
.then((response) => response.json())
.then((data) => setUserData(data));
}, [id]);
return (
<div>
<h1>User: {userData?.name}</h1>
</div>
);
}
최신 버전에서는 Loader
API를 도입하여 데이터 가져오기가 라우트 수준에서 직접 일어나도록 합니다. 이는 관심사를 분리하고 컴포넌트를 간소화하며 더 나은 동시 렌더링을 가능하게 합니다.
React Router v7 예제
import { useLoaderData } from 'react-router-dom';
export async function userLoader({ params }) {
const response = await fetch(`/api/users/${params.id}`);
return response.json();
}
function UserPage() {
const userData = useLoaderData();
return (
<div>
<h1>User: {userData.name}</h1>
</div>
);
}
// Route Configuration
<Route path="/users/:id" element={<UserPage />} loader={userLoader} />
차이점
React Router 7에서 데이터 가져오기 로직(userLoader
)은 컴포넌트에서 분리되어, 컴포넌트는 순수하게 렌더링에 집중됩니다. 이 접근 방식은 컴포넌트가 렌더링되기 전에 데이터를 사전으로 가져오를 수 있어 더 나은 사용자 경험과 원활한 전환을 가져옵니다.
2. 경로별 오류 경계
React Router 7(또는 최신 버전)에서 도입된 유용한 기능 중 하나는 오류 경계를 경로별로 정의할 수 있는 기능입니다. 이는 개발자가 더 구체적인 수준에서 오류를 처리할 수 있게 합니다. 전체 애플리케이션에 대해 단일 글로벌 오류 경계를 사용하는 대신, 개별 경로에 대해 특정 오류 경계를 정의하여 오류 처리를 더 유연하고 로컬화할 수 있습니다. 경로 수준에서의 구체적인 오류 처리가 가능합니다.
구 버전에서는 오류 처리가 글로벌이나 컴포넌트 수준에서 관리되었습니다. 이는 개발자가 모든 가능한 오류를 한 곳에서 처리하거나 다양한 컴포넌트에 복잡한 로직을 도입해야 했습니다. 아래 예제에서와 같이, ErrorBoundary
는 전체 Router
를 감싸고 있기 때문에 글로벌로 작동하며, 앱 내 모든 경로에서 발생하는 오류를 잡습니다.
React Router v5 예제
function App() {
return (
<ErrorBoundary>
<Router>
<Route path="/" exact component={HomePage} />
<Route path="/about" component={AboutPage} />
</Router>
</ErrorBoundary>
);
}
React Router 7은 경로 수준의 오류 경계를 도입하여 특정 경로에 대한 오류를 처리할 수 있게 합니다. 이는 오류 관리와 표시 방식에 대해 더 구체적인 제어가 가능하게 합니다.
React Router v7 예제
import { useRouteError } from 'react-router-dom';
function ErrorBoundary() {
const error = useRouteError();
return <div>Error: {error.message}</div>;
}
<Route path="/users/:id" element={<UserPage />} errorElement={<ErrorBoundary />} />
차이
React Router 7에서의 오류 처리는 더 모듈적이고 로컬화되었습니다. 각 라우트는 자신의 오류 처리 로직을 정의할 수 있어 앱의 다른 부분이 실패할 때 사용자 경험을 개선합니다.
3. 레이아웃 라우트의 더 나은 처리
레이아웃 라우트가 도입되어 앱의 다른 부분에서 일관된 레이아웃 관리를 가능하게 하여 코드 중복을 줄입니다.
React Router v5에서는 헤더, 푸터 또는 사이드바와 같은 레이아웃을 각 라우트나 컴포넌트에 수동으로 중복해야 했습니다. 이는 개발자가 종종 레이아웃 컴포넌트(예: Header
, Footer
)를 App
컴포넌트 내에 직접 배치하거나 다른 라우트 처리자에 반복적으로 배치하게 만들었습니다.
React Router v5 예제
import { BrowserRouter as Router, Route } from 'react-router-dom';
import Header from './Header';
import Footer from './Footer';
import HomePage from './HomePage';
import AboutPage from './AboutPage';
function App() {
return (
<Router>
<Header />
<Route path="/" exact component={HomePage} />
<Route path="/about" component={AboutPage} />
<Footer />
</Router>
);
}
React Router 7은 레이아웃 라우트를 도입하여 중첩 라우트를 감싸는 공통 레이아웃을 정의할 수 있어 코드 중복을 제거하고 더 나은 구조를 보장합니다.
React Router v7 예제
import { Outlet } from 'react-router-dom';
function SharedLayout() {
return (
<div>
<header>Header Content</header>
<main>
<Outlet /> {/* Nested routes will render here */}
</main>
<footer>Footer Content</footer>
</div>
);
}
// Route Configuration with Layout
<Route path="/" element={<SharedLayout />}>
<Route index element={<HomePage />} />
<Route path="about" element={<AboutPage />} />
</Route>
차이
레이아웃 라우트는 코드를 반복하지 않고 여러 라우트에 걸쳐 공통 레이아웃을 적용하는 깨끗하고 재사용 가능한 방법을 제공합니다. Outlet
은 자식 라우트의 占位符로 작동하여 레이아웃 관리를 훨씬 더 쉽게 만듭니다.
4. 향상된 중첩 라우팅 기능
레이아웃 요소의 상속과 더 나은 데이터 가져오기 전략을 포함한 중첩 라우트를 처리하는 더 효율적인 방법이 있습니다.
이전 버전에서는 네스티드 라우트가 가능했지만 설정이 더 복잡했습니다. 부모 컴포넌트 내에서 라우트 네스팅을 명확히 처리해야 했으며, 현재 경로를 얻기 위해 useRouteMatch()
를 사용해야 했습니다. 그런 다음 부모 컴포넌트 내부에 네스티드 라우트를 수동으로 정의해야 했습니다. 이 접근 방식은 특히 복잡한 애플리케이션에서 여러 레이어의 네스티드 라우트가 있는 경우 빠르게 복잡해질 수 있습니다.
React Router v5 예제
import { Route, useRouteMatch } from 'react-router-dom';
function Dashboard() {
const { path } = useRouteMatch();
return (
<div>
<h1>Dashboard</h1>
<Route path={`${path}/overview`} component={Overview} />
<Route path={`${path}/settings`} component={Settings} />
</div>
);
}
<Route path="/dashboard" component={Dashboard} />
React Router 7에서는 네스티드 라우트가 선언적으로 라우트 구성 내에 직접 설정되어 라우팅 구조를 단순화하고 코드를 더 읽기 쉽게 만들었습니다.
React Router v7 예제
import { Outlet } from 'react-router-dom';
function DashboardLayout() {
return (
<div>
<h1>Dashboard</h1>
<Outlet /> {/* Nested routes will render here */}
</div>
);
}
// Route Configuration
<Route path="/dashboard" element={<DashboardLayout />}>
<Route path="overview" element={<Overview />} />
<Route path="settings" element={<Settings />} />
</Route>
차이
React Router 7에서는 라우트 구성 수준에서 Outlet
컴포넌트를 사용하여 네스티드 라우트를 정의하기 때문에 관리가 더 간편합니다. 이 구조는 레이아웃과 콘텐트 간의 명확한 분리를 촉진합니다.
5. 개선된Suspense 통합
이제 React 18의 Suspense
와 동시 렌더링을 위한 더 나은 지원으로 부드러운 로딩 경험을 제공합니다.
이전 버전에서는 lazy-loaded 컴포넌트에만 Suspense
가 지원되어 복잡한 데이터 가져오기 시나리오에서 유용성이 제한되었습니다.
React Router v5 예제
import React, { Suspense, lazy } from 'react';
const HomePage = lazy(() => import('./HomePage'));
<Suspense fallback={<div>Loading</div>}>
<Route path="/" component={HomePage} />
</Suspense>
React Router 7은 Suspense
를 로더와 액션 API와 통합하여, 최소한의 노력으로 원활하고 동시적인 데이터 가져오기를 가능하게 합니다.
React Router v7 예제
import { Suspense } from 'react';
import { Route, Routes } from 'react-router-dom';
function App() {
return (
<Suspense fallback={<div>Loading</div>}>
<Routes>
<Route path="/" element={<HomePage />} />
<Route path="/about" element={<AboutPage />} />
</Routes>
</Suspense>
);
}
차이
React Router 7은 Suspense
를 라이제이션된 컴포넌트와 데이터 가져오기 모두에 사용하여, 원활한 전환과 더 반응성 있는 사용자 인터페이스를 제공합니다.
결론
React Router 7(또는 최신 버전)은 여러 강력한 기능을 도입하여 React 애플리케이션에서 라우팅을 크게 향상시킵니다. 새로운 로더와 액션 API는 선언적 데이터 가져오기를 가능하게 하여, 데이터 로직을 컴포넌트에서 분리하여 코드를 깨끗하게 만듭니다. 레이아웃 라우트는 공통 레이아웃 관리를 간소화하여 중복을 줄입니다. 嵌套 라우트는 더 효율적이고 직관적이어서 명확한 구조를 제공합니다. 또한, 라우트별 오류 경계는 세밀한 오류 처리를 제공하여 신뢰성을 높입니다. 전체 React Suspense
통합는 원활한 데이터 로딩과 사용자 경험을 지원합니다. 이러한 진보는 복잡하고 확장 가능하며 성능이 뛰어난 React 애플리케이션의 개발을 간소화시키며, React Router 7을 이전 버전보다 큰 업그레이드로 만듭니다.
Source:
https://dzone.com/articles/why-react-router-7-is-a-game-changer-for-react-devs