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
和並行渲染提供了更好的支持,以實現更平滑的加載體驗。
在舊版本中,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