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>
);
}
הגרסאות האחרונות מציגות API Loader
, שמאפשר לשלוף נתונים לישירות ברמת הניצוב. זה מפריד דאגות, מפשט קומפוננטות, ומאפשר רינדור מקביל.
דוגמה של 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
עם פונקציות Loader ו-Action APIs, ומאפשר חילוץ מידע מקבילי וחלק עם מינימום מאמץ.
דוגמה של 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 על ידי הצגת מספר תכונות חזקות. הפונקציות Loader ו-Action APIs חדשות מאפשרות חילוץ מידע דקלרטיבי, ומפרידות את לוגיקת המידע מהרכיבים לשם קוד נקי יותר. נתיבים של תבניות מספיקים את ניהול התבניות המשותפות, ומקטינים את הדופליקציה. נתיבים מונחים הם יותר יעילים ואינטואיטיביים, ומאפשרים מבנה ברור יותר. בנוסף, גבולות שגיאה לנתיב מספקים טיפול בשגיאות מקומי, ומשפרים את האמינות. האינטגרציה המלאה עם React Suspense
תומכת בטעינת מידע חלקה וחווית משתמש טובה יותר. ביחד, השיפורים הללו מפשטים את פיתוח יישומים מורכבים, סקלים ובעלי ביצועים גבוהים, והופכים את React Router 7 לשיפור משמעותי ביחס לגרסיות הקודמות.
Source:
https://dzone.com/articles/why-react-router-7-is-a-game-changer-for-react-devs