React Router 7 به تازگی منتشر شده است و به‌روزرسانی‌های بسیار مفیدی را شامل می‌شود. در این مقاله قصد داریم تا درمورد تغییرات نسخه React Router 7 بیشتر صحبت کنیم و یاد بگیریم که چگونه باید از این ویژگی‌های جدید در پروژه‌های خود استفاده کنیم.

تغییرات React Router 7 شامل چه مواردی می‌باشد؟

۱- Type Safety پیشرفته

یکی از مهم‌ترین تغییرات در نسخه ۷، سیستم Type Safety پیشرفته است. اکنون می‌توانیم از بررسی قوی‌تر تایپ و پشتیبانی از تکمیل خودکاری که بهبود پیدا کرده است در IDE خود بهره‌مند شویم.

// Before (React Router 6)
const loader = async ({ params }) => {
  const user = await getUser(params.id);
  return user;
};

// After (React Router 7)
const loader = async ({ params }: LoaderFunctionArgs) => {
  const user = await getUser(params.id);
  return json(user); // Type-safe response
};

۲- دریافت ساده‌تر داده‌ها

React Router 7 یک رویکرد شهودی‌تر برای دریافت داده با استفاده از loader و action APIهای بهبود یافته معرفی می‌کند. این پیاده‌سازی جدید، مدیریت dependencyهای داده و مدیریت stateهای loading را آسان‌تر می‌نماید.

// New data fetching pattern in v7
export const route = {
  loader: async ({ params }) => {
    const response = await fetch(`/api/users/${params.id}`);
    return json(await response.json());
  },
  element: <UserProfile />
};

۳- بهبود مدیریت خطا

مدیریت خطا در نسخه ۷ با کنترل دقیق‌تر بر روی error boundaryها، ارتقاء اساسی پیدا می‌کند. اکنون می‌توانیم مدیریت خطا را در سطح route تعریف کنیم که این کار، مدیریت و دیباگ کردن خطاها را آسان‌تر می‌کند.

const router = createBrowserRouter([
  {
    path: "/dashboard",
    element: <Dashboard />,
    errorElement: <DashboardError />,
    children: [
      {
        path: "analytics",
        element: <Analytics />,
        errorElement: <AnalyticsError />, // Specific error handling
        loader: analyticsLoader
      }
    ]
  }
]);

۴- بهبود Suspense Integration

React Router 7 یکپارچگی بهتری را با ویژگی React 18 Suspense ارائه می‌نماید که کمک می‌کند تا stateهای loading ظریف‌تر و تجربه کاربری بهتری را داشته باشیم:

import { Suspense } from 'react';
import { Await, useLoaderData } from 'react-router-dom';

function ProductPage() {
  const { product } = useLoaderData();
  
  return (
    <Suspense fallback={<ProductSkeleton />}>
      <Await resolve={product}>
        {(resolvedProduct) => <ProductDetails product={resolvedProduct} />}
      </Await>
    </Suspense>
  );
}

بررسی تغییراتی که قبل از ارتقا پروژه باید توجه بیشتری به آن‌ها داشته باشیم

قبل از این که React Router پروژه خود را به نسخه ۷ ارتقا دهیم، باید از این تغییرات مهم اطلاع داشته باشیم زیرا، ممکن است برنامه ما را تحت تأثیر قرار دهند:

۱- Required بودن آبجکت‌های Response

// This won't work in v7
export async function loader() {
  return { message: "Hello" };
}

// This is the correct way in v7
export async function loader() {
  return json({ message: "Hello" });
}

۲- تغییر در پیکربندی Route

در نسخه جدید، سینتکس پیکربندی route به‌روزرسانی شده است تا صریح‌تر و ایمن‌تر باشد:

// Old way (v6)
<Routes>
  <Route path="/dashboard" element={<Dashboard />}>
    <Route path="profile" element={<Profile />} />
  </Route>
</Routes>

// New way (v7)
const router = createBrowserRouter([
  {
    path: "/dashboard",
    element: <Dashboard />,
    children: [
      {
        path: "profile",
        element: <Profile />,
        loader: profileLoader
      }
    ]
  }
]);

۳- به‌روزرسانی Navigation API

برای این که navigation API شهودی‌تر بوده و سازگاری بیشتری داشته باشد، در نسخه ۷ اصلاحاتی داشته است:

// Old way (v6)
navigate('/dashboard');

// New way (v7)
navigation.navigate({
  to: '/dashboard',
  // New options available
  preventScrollReset: true,
  relative: 'path'
});

بررسی روش ارتقا به نسخه ۷ React Router

در ادامه یک راهنمای گام‌به‌گام برای ارتقا به نسخه ۷ را باهم بررسی می‌کنیم:

آماده‌سازی محیط توسعه

ابتدا باید مطمئن شویم که پروژه ما حداقل شرایط لازم برای انجام این کار را برآورده می‌کند:

# Update to React 18 if you haven't already
npm install react@18 react-dom@18

# Install React Router 7
npm install react-router-dom@7

به‌روزرسانی تعاریف route

مسیرهای موجود خود را به فرمت جدید تبدیل می‌کنیم:

// src/router.tsx
import { createBrowserRouter } from 'react-router-dom';

export const router = createBrowserRouter([
  {
    path: '/',
    element: <RootLayout />,
    children: [
      {
        path: 'dashboard',
        element: <Dashboard />,
        loader: dashboardLoader,
        errorElement: <DashboardError />
      }
    ]
  }
]);

به‌روزرسانی منطق دریافت داده

برای این که بتوانیم از loader و الگوهای action جدید استفاده کنیم، باید data fetching خود را مجدداً تنظیم نماییم:

// Before (v6)
function Dashboard() {
  const [data, setData] = useState(null);
  
  useEffect(() => {
    fetchDashboardData().then(setData);
  }, []);
  
  return <div>{/* render data */}</div>;
}

// After (v7)
export async function loader() {
  const data = await fetchDashboardData();
  return json(data);
}

function Dashboard() {
  const data = useLoaderData();
  return <div>{/* render data */}</div>;
}

آیا لازم است که React Router را به نسخه ۷ ارتقا دهیم؟

تصمیم برای ارتقا باید بر اساس نیازها و شرایط خاص ما باشد. در ادامه نکاتی وجود دارد که حتما باید به آن‌ها توجه کنیم:

اگر

اما اگر

جمع‌بندی

React Router 7 یک گام مهم رو به جلو از نظر type safety، data fetching و تجربه توسعه‌دهنده می‌باشد. در حالی که برخی از توسعه‌دهندگان نگرانی‌های مربوط به performance را گزارش کرده‌اند، اما پیشرفت‌های کلی در API و فانکشنالیتی، آن را به یک ارتقای قانع کننده برای بسیاری از پروژه‌ها تبدیل کرده است.

باید به این نکته توجه داشته باشیم که پس از ارتقاء برنامه خود به نسخه ۷، پروژه خود را به شکل کامل تست کنیم، زیرا اعمال یکسری از تغییرات ممکن است به روش‌های غیرمنتظره‌ای بر روی منطق routing پروژه ما تأثیر بگذارد.