React والأطر البرمجية الحديثة للواجهات الأمامية

أساسيات React الداخلية والمصالحة

5 دقيقة للقراءة

فهم كيفية عمل React من الداخل يميزك عن المرشحين الذين يعرفون فقط واجهة API السطحية. يختبر المحاورون في Meta و Google هذه المفاهيم تحديدًا.

Virtual DOM مقابل بنية Fiber

React لا يتعامل مع DOM الحقيقي مباشرة. بدلاً من ذلك، يحتفظ بتمثيل JavaScript خفيف الوزن لواجهة المستخدم.

Virtual DOM (React 15 والأقدم):

  • ينشئ React شجرة من كائنات JavaScript العادية تمثل واجهة المستخدم
  • عند تغيير الحالة، ينشئ React شجرة جديدة ويقارنها بالسابقة
  • المقارنة (المصالحة) تحدد الحد الأدنى من عمليات DOM المطلوبة
  • يطبق React هذه العمليات في دفعة واحدة

بنية Fiber (React 16+):

  • استبدل React خوارزمية المصالحة التكرارية المتزامنة بـ Fiber
  • كل مثيل مكون يُمثل بعقدة "fiber" في قائمة مترابطة
  • يمكن مقاطعة العمل وإيقافه واستئنافه — التحسين الرئيسي
  • هذا يُمكّن الأولويات: تفاعلات المستخدم تحصل على أولوية أعلى من التحديثات الخلفية
شجرة Fiber (بنية قائمة مترابطة):
  App
   ├── Header (شقيق → Sidebar)
   │    └── Nav (ابن)
   ├── Sidebar (شقيق → Main)
   │    └── Menu (ابن)
   └── Main
        └── Content (ابن)

خوارزمية المصالحة

عند تغيير الحالة، يُجري React المصالحة — مقارنة شجرتي fiber القديمة والجديدة:

القاعدة 1: أنواع عناصر مختلفة → هدم وإعادة بناء

// القديم: <div><Counter /></div>
// الجديد: <span><Counter /></span>
// يفكّ React تركيب Counter بالكامل ويُعيد تركيب مثيل جديد

القاعدة 2: نفس نوع العنصر → تحديث السمات فقط

// القديم: <div className="old" title="x" />
// الجديد: <div className="new" title="x" />
// يحدّث React فقط className، يحتفظ بعقدة DOM

القاعدة 3: المفاتيح تُعرّف عناصر القائمة عبر العروض

// بدون مفاتيح — يُعيد React عرض جميع العناصر عند تغيير القائمة
<ul>
  {items.map(item => <li>{item.name}</li>)}
</ul>

// مع مفاتيح — يعرف React بالضبط أي عناصر تغيرت
<ul>
  {items.map(item => <li key={item.id}>{item.name}</li>)}
</ul>

لماذا المفاتيح مهمة (المفضلة في المقابلات):

  • بدون مفاتيح، يطابق React الأبناء بالفهرس
  • إدراج عنصر في البداية يُزيح جميع الفهارس، مسببًا إعادة عرض كل عنصر
  • مع مفاتيح فريدة، يمكن لـ React مطابقة العناصر عبر العروض وتحديث ما تغير فقط
  • يجب أن تكون المفاتيح معرّفات مستقرة وفريدة (معرّفات قاعدة البيانات)، وليس فهارس المصفوفة للقوائم الديناميكية

الميزات المتزامنة

قدّم React 18+ العرض المتزامن، المبني على Fiber:

useTransition

يُعلّم تحديث الحالة بأنه غير عاجل، مما يسمح لـ React بالحفاظ على استجابة واجهة المستخدم:

function SearchPage() {
  const [query, setQuery] = useState('');
  const [results, setResults] = useState([]);
  const [isPending, startTransition] = useTransition();

  function handleChange(e) {
    // عاجل: تحديث الإدخال فورًا
    setQuery(e.target.value);

    // غير عاجل: تحديث النتائج يمكن مقاطعته
    startTransition(() => {
      setResults(filterLargeDataset(e.target.value));
    });
  }

  return (
    <>
      <input value={query} onChange={handleChange} />
      {isPending ? <Spinner /> : <ResultsList results={results} />}
    </>
  );
}

useDeferredValue

ينشئ نسخة مؤجلة من قيمة تتأخر عن القيمة الحالية:

function SearchResults({ query }) {
  // deferredQuery يتحدث فقط عندما يكون لدى React وقت فراغ
  const deferredQuery = useDeferredValue(query);
  const isStale = query !== deferredQuery;

  return (
    <div style={{ opacity: isStale ? 0.7 : 1 }}>
      <ExpensiveList query={deferredQuery} />
    </div>
  );
}

الفرق الرئيسي: useTransition يلف مُعدّل الحالة (أنت تتحكم متى تنتقل). useDeferredValue يلف قيمة (المكون الذي يستهلك القيمة يقرر التأجيل).

مترجم React

مترجم React (أُصدر بشكل منفصل عن React 19) هو أداة بناء تُضيف التخزين المؤقت التلقائي للمكونات:

// قبل مترجم React: تخزين مؤقت يدوي
const MemoizedChild = React.memo(({ data }) => {
  const processed = useMemo(() => expensiveCalc(data), [data]);
  const handler = useCallback(() => doSomething(data), [data]);
  return <div onClick={handler}>{processed}</div>;
});

// مع مترجم React: اكتب كودًا طبيعيًا
// المترجم يضيف التخزين المؤقت تلقائيًا حيث يلزم
function Child({ data }) {
  const processed = expensiveCalc(data);
  const handler = () => doSomething(data);
  return <div onClick={handler}>{processed}</div>;
}
// المترجم يحوّل هذا في وقت البناء ليتضمن
// ما يعادل memo و useMemo و useCallback

نصيحة للمقابلات: عند السؤال عن أداء React، اذكر التقدم: React.memo اليدوي → useMemo/useCallback → مترجم React. أظهر وعيًا بأن النظام البيئي يتجه نحو التحسين التلقائي.

التالي: سنتعمق في الخطافات وأنماط إدارة الحالة. :::

اختبار

الوحدة 3: React والأطر البرمجية الحديثة

خذ الاختبار