التصيير والتأكيد

قبل أن يتم عرض مكوناتك في الشاشة، يجب أن يتم تصييرها بواسطة React. فهم الخطوات في هذه العملية سيساعدك على التفكير في كيفية تنفيذ الكود الخاص بك وشرح سلوكه.

You will learn

  • ماذا يعني التصيير في React
  • متى ولماذا يقوم React بتصيير مكون
  • خطوات عرض مكون في الشاشة
  • لماذا التصيير لا يقدم دائمًا تحديث DOM

تخيل أن مكوناتك طهاة في المطبخ، يطبخون وصفات لذيذة، في هذا السيناريو، React هو النادل الذي يسجل طلبات الزبائن ويقدمها لهم. هذه العملية من طلب وتقديم الواجهة لها ثلاث خطوات:

  1. تنشيط عملية التصيير (تسليم طلب الزبون للمطبخ)
  2. تصيير المكون (إعداد الطلب في المطبخ)
  3. التأكيد على DOM (وضع الطلب على الطاولة)
  1. تمثل React دور خادم المطعم، تجلب الطلبات من المستخدمين وتوصلها إلى مطبخ المكونات
    تنشيط
  2. يقدم الطاهي (بطاقة Card) مكون Card جديد لـ React
  3. يقدم React البطاقة للمستخدم على طاولته
    تأكيد

Illustrated by Rachel Lee Nabors

الخطوة الأولى: تنشيط التصيير

هناك سببان لتنفيذ تصيير المكون:

  1. التصيير الأوَّلِي للمكون. (initial render)
  2. تم تحديث حالة المكون (أو أحد آبائه). (state)

التصيير الأوَّلِي

عند بدء تشغيل التطبيق، تحتاج لبدء التصيير الأوَّلِي، تخفي إطارات العمل ومحررات الأكواد البسيطة هذا الكود، لكنه يتم بواسطة استدعاء createRoot مستهدفًا عنصر DOM، ثم استدعاء طريقة render مع المكون الخاص بك:

import Image from './Image.js';
import { createRoot } from 'react-dom/client';

const root = createRoot(document.getElementById('root'))
root.render(<Image />);

جرب عمل تعليق على السطر الذي يستدعي root.render() وانظر كيف تختفي الصورة.

مثل هذا:

// root.render(<Image />);

إعادة التصيير عند تحديث الحالة

بمجرد أن يتم تصيير المكون لأول مرة، يمكنك تنشيط عمليات التصيير الأخرى عن طريق تحديث حالته باستخدام دالة set. تحديث حالة المكون الخاص بك يضع تلقائيًا عملية تصيير في قائمة الانتظار. (يمكنك تخيل هذه العمليات على أنها طلبات من زبون المطعم للحصول على الشاي أو الحلويات أو أي شيء آخر بعد طلبه الأول، اعتمادًا على حالة عطشه أو جوعه.)

  1. React كخادم في مطعم، يقدم واجهة مستخدم بطاقة للمستخدم، ويمثل المستخدم بزبون مع مؤشر لرأسه. يعبر الزبون عن رغبته في الحصول على بطاقة وردية، وليس سوداء!
    تحديث الحالة...
  2. يعود React إلى مطبخ المكونات ويخبر طاهي البطاقات أنه يحتاج إلى بطاقة وردية.
    ...يؤدي إلى...
  3. يعطي طاهي البطاقات React البطاقة الوردية.
    ...تصيير!

Illustrated by Rachel Lee Nabors

الخطوة الثانية: يقوم React بتصيير مكوناتك

بعد تنشيط عملية التصيير، يقوم React بتصيير مكوناتك لمعرفة ما يجب عرضه على الشاشة. “التصيير” هو استدعاء React لمكوناتك.

  • عند التصيير الأوَّلِي، سينشئ React المكون الأصل.
  • عند التصيير اللاحق، سينشئ React المكون الذي أدى تحديث حالته إلى التصيير.

هذه العملية تتكرر: إذا كان المكون المحدث يعيد مكونًا آخر، فسيقوم React بتصيير هذا المكون التالي، وإذا كان هذا المكون أيضًا يعيد شيئًا ما، فسيقوم بتصيير هذا المكون التالي، وهكذا. ستستمر العملية حتى لا تكون هناك مكونات متداخلة أخرى ويعرف React بالضبط ما يجب عرضه على الشاشة.

في المثال التالي، سينفذ React Gallery() و Image() عدة مرات:

export default function Gallery() {
  return (
    <section>
      <h1>منحوتات ملهمة</h1>
      <Image />
      <Image />
      <Image />
    </section>
  );
}

function Image() {
  return (
    <img
      src="https://i.imgur.com/ZF6s192.jpg"
      alt="'Floralis Generica' لإدواردو كاتالانو: منحوتة زهرة معدنية عملاقة بتلات عاكسة للضوء"
    />
  );
}

  • أثناء التصيير الأولي ستقوم React بإنشاء عناصر DOM لعلامات <section>، <h1>، وثلاث علامات <img>.
  • أثناء التصيير اللاحق سيحسب الخصائص التي تغيرت منذ التصيير السابق، إن وجدت. لن يفعل أي شيء بهذه المعلومات حتى الخطوة التالية، وهي مرحلة التأكيد.

Pitfall

دائمًا يجب أن يكون التصيير محسوبًا بدقة:

  • إن كان نفس المدخلات يجب أن يحصل على نفس الناتج. بالنظر إلى نفس الطلبات، يجب أن يعيد المكون نفس JSX دائمًا. (عندما يطلب شخص ما سلطة مع الطماطم، فلا ينبغي أن يتلقى سلطة مع البصل!)
  • يهتم فقط بما يخصه. لا ينبغي أن يغير أي كائنات أو متغيرات كانت موجودة قبل التصيير. (لا ينبغي أن يؤثر طلب واحد على طلبات الآخرين.)

وإلا، يمكنك أن تواجه أخطاءً محيّرة وسلوكًا غير متوقع مع تعقيد بيئة الكود. عند التطوير في “وضع صارم (Srrict Mode)”، ينشئ React كل وظيفة مكون مرتين، مما يساعد على كشف الأخطاء الناتجة عن الوظائف غير النقية.

Deep Dive

تحسين الأداء

التصرف الافتراضي لتصيير كل المكونات المتفرعة عن المكون الذي تم تحديثة ليس مثاليًا للأداء إذا كان المكون المحدث عاليًا جدًا في شجرة المكونات. إذا واجهتك مشكلة في الأداء، فهناك طرق مختلفة لحلها، مشروحة في قسم الأداء. لا تستعجل محاولة تحسين الأداء!

الخطوة الثالثة: يؤكد React التغييرات على DOM

بعد تصيير (استدعاء) للمكونات، سيعدل React الـ DOM.

  • أثناء التصيير المبدئي سيستخدمReact DOM API appendChild() لوضع جميع عناصر DOM التي أنشأها على الشاشة.
  • أثناء إعادة التصيير سينفذ React العمليات اللازمة (التي تم حسابها أثناء التصيير!) لجعل DOM يتطابق مع أحدث نتيجة تصيير.

يغيّر React عناصر DOM فقط إذا كان هناك فرق بين التصييرين. على سبيل المثال، هناك مكون يقوم بإعادة التصيير مع اختلاف الخصائص المُمَرَّرة من المكون الأصلي كل ثانية. لاحظ كيف يمكنك إضافة بعض النص إلى <input>، وتحديث value، ولكن النص لا يختفي عند إعادة تصيير المكون:

export default function Clock({ time }) {
  return (
    <>
      <h1>{time}</h1>
      <input />
    </>
  );
}

هذا يعمل لأنه أثناء هذه الخطوة الأخيرة، يحدّث React محتوى <h1> بالوقت الجديد. يرى React أن <input> يظهر في JSX في نفس المكان كالمرة السابقة، لذلك لا يلمس React الـ <input> - أو value!

الخاتمة: رسم المتصفح

بعد الانتهاء من التصيير وتحديث React لـ DOM، سيعيد المتصفح رسم الشاشة. على الرغم من أن هذه العملية معروفة باسم “تصيير المتصفح”، سنشير إليها باسم “رسم” طوال التوثيق لتجنب الخلط.

رسم المتصفح: لا يزال حيًَا مع عنصر البطاقة'.

Illustrated by Rachel Lee Nabors

Recap

  • يحدث أي تحديث على الشاشة في تطبيق React في ثلاث خطوات:
    1. التنشيط
    2. التصيير
    3. التأكيد
  • يمكنك استخدام الوضع الصارم للعثور على الأخطاء في مكوناتك
  • لا يلمس React الـ DOM إذا كانت نتيجة التصيير هي نفسها كالمرة السابقة