كيف يعمل React تحت الغطاء

React هي مكتبة JavaScript شائعة جدًا. مع ما يزيد عن 5.5 مليون عملية تنزيل أسبوعية ، تتمتع React بشعبية كبيرة. لكن لا يعرف الكثير من مطوري React كيف تعمل React تحت الغطاء.

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

ولكن قبل أن نبدأ ، إذا كنت أحد مطوري React ، فلدي بعض الأخبار المثيرة لك! بمجرد إكمال هذه المقالة ، ستتمكن من تطوير شيء رائع باستخدام React والفوز بجوائز في الطريق :)

ماذا تفعل React؟

في جوهرها ، تحتفظ React أساسًا بشجرة لك. هذه الشجرة قادرة على إجراء حسابات فرق فعالة على العقد.

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

JSX هو سكر نحوي

لا يوجد شيء مثل JSX - لا لجافا سكريبت ولا للمتصفح. JSX هو ببساطة سكر نحوي لإنشاء كائنات JavaScript محددة للغاية.

عندما تكتب شيئًا مثل:

const tag = 

Hello

ما تفعله في الأساس هو هذا:

const tag = React.createElement("h1", {}, "Hello")

كما ترى ، عندما تبدأ في كتابة أشياء متداخلة ، ليس من الصعب فقط كتابة التعليمات البرمجية ، ولكن أيضًا يصبح من غير الملائم الاحتفاظ بمثل هذا الرمز البرمجي. وبالتالي ، فإن JSX يساعدك على إضفاء نظافة HTML على قوة JavaScript.

ولكن ما الذي تفعله React.createElement بنفسها؟ يقوم بإنشاء كائن JavaScript قديم عادي. في الواقع ، يمكنك الاتصال به يدويًا وترى بنفسك!

كما ترى ، لدينا كائن مثل هذا:

{ $$typeof: Symbol(react.element), key: null, props: {children: "Hello"}, ref: null, type: "div" }

وإذا بدأنا في تداخل العناصر مثل هذا:

React.createElement('div', { }, React.createElement('p', {}, 'A p inside a div') ) 

سنبدأ في الحصول على كائنات متداخلة:

الآن كما تعلم ، بمجرد تحليل كل JSX وحل جميع استدعاءات React.createElement ، نصل بكائن واحد متداخل عملاق مثل أعلاه.

رد فعل العارض

الآن ، إذا عدت إلى النقطة التي بدأنا فيها تشغيل تطبيقنا ، فسترى أنه في ملف index.js الخاص بك ، ستجد السطر التالي:

// .. prev code ReactDOM.render(, container)

من الأعلى ، نعلم أنه عند الانتهاء من التحليل ، يكون هذا مجرد كائن ضخم من عناصر React. إذن كيف يمكن لـ React إنشاء علامات div و p فعلية للخروج منها؟ قابل ReactDOM.

تقوم ReactDOM بدورها بإنشاء عقد بشكل متكرر بناءً على خاصية "النوع" وإلحاقها أخيرًا بـ DOM.

يجب أن يكون واضحًا في هذه المرحلة أن فصل React عن العارضين هو في الواقع خطوة رائعة! ما تفعله React هو ببساطة إنشاء شجرة لواجهة المستخدم التي يمكن استخدامها ليس فقط على الويب ، ولكن في بيئات مثل الهاتف المحمول أيضًا ، بالنظر إلى توفر عارض قادر على التواصل مع نظام التشغيل المضيف. هنا ، يأتي React Native للعب. كما ترى ، يستخدم React Native مكتبة React ، لكن ليس ReactDOM كعرض العرض. بدلاً من ذلك ، فإن الحزمة الأصلية التي تتفاعل نفسها هي عارض.

نقوم بذلك في تطبيق أصلي للتفاعل لبدء التطبيق:

const { AppRegistry } = require('react-native') AppRegistry.registerComponent('app', () => MainComponent)

نظرة! لا يوجد رد فعل. لما لا؟ نظرًا لعدم وجود طرق مثل appendChild ، فليس لدينا بيئة مثل DOM. بدلاً من ذلك ، بالنسبة للهواتف المحمولة ، نحتاج إلى دعم واجهة المستخدم مباشرة من نظام التشغيل. لكن مكتبة React لا تحتاج إلى معرفة ذلك ، فإن العارض (React Native) يعتني بذلك.

رد فعل المصالحة

عندما نقول أن React تحتفظ بنسخة من DOM باستخدام DOM الظاهري في JavaScript ، وتستخدم لتقسيمها إلى أي تغييرات وتطبيقها على DOM الحقيقي ، فإننا لا نريد أن يفرض React طريقه. رد فعل ، في الواقع يفعل مصالحة كسولة للغاية. ستجعل React أقل قدر ممكن من التغييرات ، أي ستحاول إعادة استخدام العناصر والسمات وحتى الأنماط إن أمكن!

ضع في اعتبارك هذا المثال:

stuff

لنفترض أنك قمت بتغيير تعبير JSX إلى التعبير أدناه باستخدام بعض الشروط أو بعض الحالات:

something else

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

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

I did not change

إذا قمت بتغيير JSX إلى ما يلي باستخدام الحالة / الحالة:

I did not change

على الرغم من أنه يمكنك أن ترى أننا لسنا بحاجة إلى إعادة إنشاء علامة p الداخلية ، إلا أن React ليس لديها طريقة لمعرفة ذلك أثناء عبور الشجرة من أعلى (ما لم تقم بالطبع بإجراء فرق ثقيل في الشجرة ، وهي خوارزميات باهظة الثمن أكثر من يتبع رد فعل O (n) الاستدلال من أجل الاختلاف). لذلك ، قررت React تدمير جميع الأطفال (أي استدعاء وظائف التنظيف الخاصة بهم في useEffect ، أو componentWillUnmount في المكونات المستندة إلى الصنف) وإعادة تكوين الأبناء من الصفر.

تفاعل المفاتيح

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


    
  • A
  • B

ضع في اعتبارك أنه تم تغيير هذا إلى ما يلي حسب الحالة / الحالة:


   
  • Z
  • A
  • B

    الآن ، عندما تبدأ React بمقارنة قائمتين للاختلاف ، فإنها ستكتشف الفرق في العقدة الفرعية 1 ، وتحوّل A القديم إلى Z الجديد ، ثم مرة أخرى في العقدة الفرعية 2 ، ستحولها من B القديمة إلى A الجديدة ، ثم ألحق أخيرًا العقدة B الجديدة.

    ومع ذلك ، كان من الأفضل الحفاظ على العقدتين A و B الحاليتين وتثبيت العقدة Z فقط. ولكن كيف ستعرف React بذلك؟ سوف تساعد مفاتيح رد الفعل.

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

    
        
    • A
    • B

    الآن ، إذا تم تغيير هذا إلى:

    
        
    • Z
    • A
    • B

    ستعرف React الآن أن المفتاحين "A" و "B" موجودان بالفعل ، لذلك نحتاج فقط إلى إضافة العنصر الجديد بالمفتاح "Z".

    هل أنت مطور React؟ أظهر مهاراتك في React من خلال تطوير لعبة تفاعلية مدتها 3 دقائق في React واربح هوديس وقمصان وأكواب قهوة ! شارك في codecomp من خلال الانضمام إلى خادم خلاف codedamn هنا

    كانت هذه بعض المفاهيم المهمة التي أعتقد أنها ستكون مفيدة حقًا لك كمطورين لـ React لبدء فهم جوهر React وكيف تعمل بالفعل. لا تتردد في تمرير أي اقتراحات أو أسئلة لديك حول نفس الشيء.

    يمكنك متابعتي على تويتر للمزيد من تغريدات وأشياء JS / الترميز. سلام!