انتقل إلى محتوى الدرس
الدرس 19
دورة ReactJS

دورة التصيير والاعتماد والحالة كلقطة ثابتةRender Commit and State as a Snapshot

تتبّع مراحل التحفيز والتصيير والاعتماد الثلاث في React، وافهم كيف تتصرف الحالة كلقطة ثابتة في كل تصيير، وتجميع التحديثات ودوال التحديث والتهيئة الكسولة.
أقسام الدرس
6
الأمثلة
4
اللغة
العربية
تاريخ النشر
غير محدد
المشاهدات
0
محتوى الدرس
في هذا الدرس 6تصفّح المواضيع

يمر كل تحديث يظهر على شاشة تطبيق React عبر خط أنابيب هندسي واضح من ثلاث مراحل متتابعة:

  1. تحفيز التصيير (Trigger): ينطلق إما عند التركيب الأولي للتطبيق عبر createRoot أو عند استدعاء دالة تحديث حالة مثل setSeats().
  2. تصيير المكون (Render): تستدعي React دالة المكون النقية لحساب شجرة JSX الجديدة.
  3. الاعتماد في المتصفح (Commit): تطبّق React الفروق الفعلية فقط على عقد DOM المتغيرة دون المساس بالعناصر الثابتة.
HTML
import { useState } from 'react';

function OrderTicket() {
  const [n, setN] = useState(1);
  return (
    <div className="rx-card">
      <p>Tickets Requested: {n}</p>
      <input placeholder="Type note (preserved!)" />
      <button onClick={() => setN(n + 1)}>+1</button>
    </div>
  );
}

تتصرف الحالة في React مثل لقطة فوتوغرافية ثابتة (Snapshot) خاصة بكل عملية تصيير؛ فاستدعاء setCount(count + 1) لا يغيّر قيمة المتغير count داخل دالة الحدث الجارية حالياً، بل تظل قيمته ثابتة حتى تنتهي الدالة، وتجدول React تصييراً جديداً يحمل لقطة محدثة بالقيمة الجديدة.

HTML
import { useState } from 'react';

function SnapshotTrap() {
  const [score, setScore] = useState(0);
  function bump() {
    setScore(score + 1);
    setScore(score + 1);
  }
  return <button onClick={bump}>Pts: {score}</button>;
}

يفسر نموذج اللقطة الثابتة أيضاً سلوك المؤقتات والدوال غير المتزامنة مثل setTimeout()؛ فالدالة المجدولة تقرأ قيمة الحالة التي التُقطت في التصيير الذي أنشأ ذلك الحدث، حتى لو نقر المستخدم لاحقاً وولّد تصييرات أحدث بقيم مختلفة.

مخطط المراحل الثلاث لتحديث الواجهة في React: مرحلة التحفيز ثم مرحلة التصيير كلقطة ثابتة ثم مرحلة الاعتماد على DOM

ماذا يحدث عندما تستدعي دالة نقر واحدة ثلاث دوال تحديث منفصلة متتالية؟ تنتظر React حتى ينتهي تنفيذ جميع أسطر معالج الحدث بالكامل ثم تجري إعادة تصيير مجمعة واحدة فقط، وتُعرف هذه الميزة باسم التجميع التلقائي (Automatic Batching) لمنع الرسوم الجزئية المهدرة للأداء.

عندما تحتاج فعلياً لتحديث متغير الحالة نفسه عدة مرات متتالية في حدث واحد أو الاعتماد المضمون على آخر قيمة مجدولة، مرّر دالة تحديث نقية (Updater Function) بصيغة setCount(c => c + 1)؛ إذ تضعها React في طابور مرتب وتمرر ناتج كل دالة كمدخل للدالة التي تليها.

HTML
import { useState } from 'react';

function ComboCounter() {
  const [pts, setPts] = useState(0);
  function addThree() {
    setPts((p) => p + 1);
    setPts((p) => p + 1);
    setPts((p) => p + 1);
  }
  return <button onClick={addThree}>XP: {pts}</button>;
}

أخيراً، إذا كانت القيمة الأولية للحالة تتطلب حساباً مكلفاً مثل توليد مصفوفة مقاعد كبيرة أو تحليل نص مخزن، فتجنب كتابة useState(buildMatrix()) لأن الأقواس ستشغل الدالة هدراً في كل إعادة تصيير! بدلاً من ذلك مرّر دالة تهيئة كسولة (Lazy Initializer) بصيغة useState(() => buildMatrix()) لتنفذها React مرة واحدة فقط عند التركيب الأول. قارن الآليات في الجدول التالي:

صيغة الاستدعاءالمثال البرمجيالسلوك الدقيق وقت التشغيل
استبدال بقيمة اللقطةsetCount(count + 1)يعتمد على قيمة اللقطة الثابتة للتصيير الحالي
دالة التحديث المتسلسلةsetCount(c => c + 1)تقرأ أحدث قيمة في الطابور وتدعم التحديثات المتتالية
تهيئة مبكرة مهدرةuseState(heavyCalc())تُشغّل الدالة المكلفة في كل إعادة رسم دون حاجة
تهيئة كسولة عالية الكفاءةuseState(() => heavyCalc())تُشغّل دالة الحساب مرة وحيدة عند التركيب الأول
HTML
import { useState } from 'react';

function createInitialSeats() {
  return ['A1', 'A2', 'B1', 'B2'];
}

function SeatHall() {
  const [seats] = useState(createInitialSeats);
  return <p>Loaded {seats.length} seats once.</p>;
}
خلاصة المعرفة ومحطة الانتقال

ملخص الدرس

حصاد الدرس

مراجعة مركّزة لأهم المفاهيم والقواعد الهندسية التي أتقنتها في هذا الدرس قبل التطبيق العملي

ماذا تعلّمت في هذا الدرس؟

تتبعت في هذا الدرس دورة التحفيز والتصيير والاعتماد، وفهمت ثبات لقطة الحالة داخل المعالجات والمؤقتات، واستفدت من التجميع التلقائي للتحديثات وطوابير دوال التحديث والتهيئة الكسولة عالية الكفاءة. الخطوة التالية: انتقل الآن إلى الدرس رقم 20 «تحديث الكائنات في الحالة دون تعديل مباشر» لمواصلة البناء التراكمي المتدرج في مسار React الحديث.

مشاركة

هل كان هذا الدرس مفيدًا؟

جارٍ تحميل الآراء…

ابنِ لغتك البرمجية

المصطلحات4

راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.

0 / 4 مفهومةأول بطاقة، أول خطوة
01 State Snapshot لقطة الحالة
القيمة الثابتة لمتغير الحالة خلال دورة تصيير واحدة والتي تقرأها جميع الدوال المنشأة في تلك اللقطة.
للمراجعة
02 Commit Phase مرحلة الاعتماد
المرحلة الثالثة بعد التصيير والتي تطبق فيها React الفروق المحسوبة الفعلية على شجرة المتصفح.
للمراجعة
03 Automatic Batching التجميع التلقائي للتحديثات
دمج React لعدة استدعاءات تحديث حالة متتالية في عملية إعادة تصيير واحدة عالية الكفاءة.
للمراجعة
04 Lazy Initializer دالة التهيئة الكسولة
دالة بدون معاملات تُمرر إلى useState لتشغيل الحساب الابتدائي المكلف مرة واحدة فقط عند التركيب.
للمراجعة

اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.

حروف قليلة. معنى كامل.

الاختصارات4

راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.

0 / 4 مفهومةأول بطاقة، أول خطوة
01 DOM DOM
Document Object Model
شجرة عناصر المتصفح الحية التي تُحدّث انتقائياً بأقل تكلفة خلال مرحلة الاعتماد.
للمراجعة
02 FIFO FIFO
First In, First Out
نظام الطابور المتسلسل الذي تعالج به React دوال التحديث المجدولة بالترتيب عند التصيير التالي.
للمراجعة
03 UI UI
User Interface
المخرجات البصرية المحسوبة بوصفها دالة نقية للقطة الحالة الحالية.
للمراجعة
04 JS JS
JavaScript
قواعد الإغلاق اللفظي في اللغة التي تفسر احتفاظ المؤقتات بقيمة اللقطة التي أنشأتها.
للمراجعة

اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.

من الفهم للتطبيق

مهامك قبل الاختبار

خطوة صغيرة كل مرة. وإنجاز تقدر ترجع له.

0/2مهام منجزة
  1. افتح مثال عداد النقاط في محرر التجريب وأضف زراً يجدول دالتي تحديث بمجموع 5 نقاط وتحقق من دقة النتيجة.

  2. افتح مثال التهيئة الكسولة في محرر التجريب وانقر زر إعادة التصيير خمس مرات للتأكد من بقاء عدد استدعاءات التهيئة عند 1.

تأشير المهمة إقرار منك بإتمامها، وليس تصحيحًا آليًا للكود. يُحفظ تقدمك في حسابك.

مساحة التحدي

اختبر فهمك.
ووصلها للإتقان.

كل سؤال خطوة لقدّام. اختار، اكتب كود، وشوف نتيجتك فورًا.

10أسئلة 2أنواع تحديات 100%هدف الإتقان
تصحيح تلقائي. فرص بلا حدود.

أكمل المهام، واجمع كل الإجابات الصحيحة. أقل من 100%؟ راجع وأعد المحاولة.

الأسئلة متاحة للاطلاع. سجّل الدخول للتفاعل وحفظ تقدمك.

لمحة عن التحدي10 أسئلة تنتظرك
01

إذا كانت قيمة count تساوي 0 في التصيير الحالي واستدعت دالة النقر setCount(count + 1) ثلاث مرات متتالية، فكم ستصبح قيمة count؟

تظل count تساوي 0 طوال اللقطة الحالية، لذا تطلب الاستدعاءات الثلاثة ضبط القيمة على 1 فتصبح النتيجة 1.

02

أي صياغة برمجية تضمن زيادة المتغير count ثلاث مرات متتالية داخل نفس دالة الحدث؟

تمرير دالة التحديث setCount(c => c + 1) ثلاث مرات يضعها في طابور متسلسل يعتمد آخر قيمة.

03

ما المراحل الثلاث المتتابعة لتحديث واجهة الشاشة في مكتبة React؟

تبدأ بتحفيز التحديث، ثم تصيير دالة المكون، وأخيراً اعتماد التغييرات في شجرة DOM.

04

في الإصدار الثامن عشر من React، تُجمع عدة تحديثات للحالة داخل دالة نقر واحدة في عملية إعادة تصيير واحدة تلقائياً.

صواب؛ إذ يمنع التجميع التلقائي عمليات الرسم الجزئية المتكررة ويحسن الأداء.

05

كيف تمرر دالة التهيئة المكلفة buildInitialBoard إلى useState بحيث تعمل مرة واحدة فقط عند التركيب الأول؟

نمرر مرجع الدالة useState(buildInitialBoard) أو دالة سهمية بدون استدعاء فوري بالأقواس.

06

تقرأ دالة setTimeout المنشأة داخل معالج النقر قيمة لقطة الحالة التي كانت موجودة لحظة النقر حتى لو حدثت تصييرات أحدث بعدها.

صواب؛ لأن كل دورة تصيير تحتفظ بنطاق إغلاق مستقل لقيم الحالة الخاصة بها.

07

خلال مرحلة الاعتماد Commit، تهدم React جميع عناصر DOM المجاورة غير المتغيرة وتعيد بناءها من الصفر.

خطأ؛ إذ تعدّل React العقد والسمات التي تغيرت فعلياً فقط وتحافظ على بقية العناصر كما هي.

08

يجب أن تكون دوال التحديث الممررة إلى setState(prev => next) دوال نقية خالية من التأثيرات الجانبية.

صواب؛ لأنها تعمل أثناء مرحلة التصيير وتختبرها React مرتين في وضع StrictMode للتأكد من نقائها.

09

إذا بدأت count بالقيمة 5 ونفذ المعالج setCount(count + 2) متبوعاً بـ setCount(c => c * 2)، فكم تصبح النتيجة النهائية؟

تضبط الخطوة الأولى القيمة في الطابور على 7، ثم تستلم دالة التحديث القيمة 7 وتضربها في 2 لتصبح 14.

10

ما العيب الأدائي في كتابة useState(parseHugeData()) بأقواس الاستدعاء المباشر؟

تُنفذ الدالة الثقيلة في كل إعادة تصيير للمكون رغم أن React تتجاهل ناتجها بعد التصيير الأول.