انتخاب ابزار مناسب بر اساس نوع مسئله

در درس قبل با چند ابزار رایج اکوسیستم آشنا شدیم، بدون قضاوت درباره برتری یکی بر دیگری. در این درس آخر فصل، همه چیزهایی که در این فصل دیدیم را در قالب چند سؤال عملی جمع می‌کنیم که می‌توانند راهنمای انتخاب باشند؛ نه یک فرمول قطعی، بلکه چارچوبی برای فکر کردن.

سؤال اول: آیا اصلاً با Server State طرفید؟

همان‌طور که در فصل چهاردهم و درس دوم همین فصل دیدیم، اگر مشکل اصلی شما Caching، Staleness یا هم‌زمانی چند درخواست است، پاسخ درست معمولاً یک کتابخانه تخصصی Server State است، نه یک ابزار عمومی مدیریت Client State مثل Redux یا Zustand. استفاده از ابزار عمومی برای این نوع مسئله، یعنی بازسازی دستی همان منطقی که آن کتابخانه‌ها آماده و آزموده‌شده ارائه می‌دهند.

سؤال دوم: آیا مشکل واقعاً Prop Drilling یا تعدد منبع تغییر است؟

اگر مشکل صرفاً انتقال یک یا چند مقدار به عمق درخت است، طبق چیزی که در فصل هشتم و درس سوم همین فصل دیدیم، Context به‌تنهایی معمولاً کافی است. نیاز واقعی به ابزار بیرونی، وقتی مطرح می‌شود که منطق تغییر State، پیچیده و پخش‌شده در نقاط زیادی از برنامه باشد.

سؤال سوم: تیم چقدر با React خام راحت است؟

ترکیب useReducer و Context، که در فصل نهم ساختیم، معمولاً برای تیم‌هایی که عمیقاً با مدل ذهنی خود React آشنا هستند، انتخاب طبیعی‌تری است. تیم‌هایی که از قبل با الگوی Reducer/Action/Store (مثلاً از پروژه‌های دیگر) آشنا هستند، ممکن است در Redux احساس راحتی بیشتری کنند؛ همین آشنایی قبلی، خودش یک معیار واقعی است، نه فقط ویژگی‌های فنی کتابخانه.

سؤال چهارم: حساسیت به تعداد Re-render چقدر بالاست؟

اگر پروفایل کردن برنامه (همان کاری که در فصل سیزدهم با React DevTools یاد گرفتیم) نشان داده که Re-renderهای ناشی از تغییرات State، خودشان یک گلوگاه عملکردی هستند، رویکردهای Atomic مثل Jotai، که در درس قبل دیدیم، می‌توانند مفید باشند؛ چون طبیعتاً هر کامپوننت فقط به بخشی که واقعاً استفاده می‌کند وابسته می‌شود.

یک جدول خلاصه برای مرور ذهنی

مسئله اصلی جهت‌گیری پیشنهادی
Caching و داده سرور کتابخانه تخصصی Server State
انتقال چند مقدار ساده در عمق درخت Context ساده
منطق پیچیده و پخش‌شده با تیم آشنا به React useReducer + Context، یا Redux
حساسیت بالا به Re-render رویکرد Atomic

یک هشدار پایانی: این تصمیم، برگشت‌ناپذیر نیست، اما ارزان هم نیست

همان‌طور که در درس چهارم این فصل دیدیم، تغییر ابزار مدیریت State در میانه یک پروژه بزرگ، کار ساده‌ای نیست. بهترین راه برای کاهش این ریسک، شروع با ساده‌ترین ابزاری است که نیاز فعلی را برطرف می‌کند و ارتقا به ابزار پیچیده‌تر، فقط زمانی که یکی از نشانه‌های واقعی (که در درس سوم دیدیم) ظاهر شود.

مثال قابل اجرا

در این مثال، یک تصمیم‌گیری ساده بین دو رویکرد (Context واحد در برابر دو Context مجزا) به‌صورت زنده نشان داده شده است.

مقایسه یک Context واحد با دو Context مجزا
import { createContext, useContext, useState } from "react";

const UserContext = createContext(null);
const ThemeContext = createContext(null);

function UserLabel() {
  const user = useContext(UserContext);
  return <p>کاربر: {user}</p>;
}

function ThemeLabel() {
  const theme = useContext(ThemeContext);
  return <p>تم: {theme}</p>;
}

function App() {
  const [user] = useState("سارا");
  const [theme, setTheme] = useState("روشن");

  return (
    <UserContext.Provider value={user}>
      <ThemeContext.Provider value={theme}>
        <UserLabel />
        <ThemeLabel />
        <button onClick={() => setTheme(theme === "روشن" ? "تیره" : "روشن")}>
          تغییر تم
        </button>
      </ThemeContext.Provider>
    </UserContext.Provider>
  );
}
برای دیدن پیش‌نمایش کامپوننت، روی Run بزنید.

جمع‌بندی

انتخاب ابزار مناسب مدیریت State، به چهار سؤال اصلی برمی‌گردد: آیا با Server State طرفید، آیا مشکل واقعاً فراتر از یک Context ساده است، تیم چقدر با React خام راحت است، و حساسیت به Re-render چقدر بالاست. این تصمیم باید همیشه با شروع ساده و حرکت تدریجی گرفته شود، نه یک انتخاب قطعی از روز اول. با این درس، فصل شانزدهم به پایان می‌رسد و در ادامه به آزمون فصل ۱۶ می‌رویم.