خطافات React هي ميزة ظهرت بعد الألياف، لذلك يعتقد الكثير من الناس خطأً أن الخطافات يجب أن تعتمد على الألياف ليتم تنفيذها.
الآن، لا يتم تنفيذ الخطافات في رد الفعل فحسب، بل أيضًا في أطر عمل مثل preact وreact ssr وmidway، ولا يعتمد تنفيذها على الألياف.
دعونا نلقي نظرة على كيفية تنفيذ الخطافات في هذه الأطر المختلفة:
تصف React الواجهة من خلال jsx، والتي سيتم تجميعها في دالة عرض بواسطة أدوات الترجمة مثل babel أو tsc، ثم يتم تنفيذها لإنشاء vdom:
وظيفة التجسيد هنا كانت React.createElement قبل React17:
بعد React 17، تم تغييره إلى jsx:
سيتم تقديم وقت تشغيل jsx هذا تلقائيًا، وليست هناك حاجة للاحتفاظ باستيراد React لكل مكون كما كان من قبل.
يؤدي تنفيذ وظيفة العرض إلى إنشاء vdom:
هيكل vdom هو مثل هذا:
قبل React16، كان سيتم تصيير هذا vdom بشكل متكرر، مع إضافة وحذف وتعديل dom الحقيقي.
بعد أن قدم React16 بنية الألياف، كانت هناك خطوة إضافية: قم أولاً بتحويل vdom إلى ألياف، ثم قم بتصيير الألياف.
تسمى عملية تحويل vdom إلى ألياف بالمصالحة، وتسمى العملية النهائية لإضافة وحذف وتعديل الدوم الحقيقي بالالتزام.
لماذا نحتاج إلى إجراء مثل هذا التحويل؟
نظرًا لأن vdom يحتوي فقط على إشارات إلى العقد الفرعية الفرعية، ولا توجد إشارات إلى العقدة الأصلية والعقد الشقيقة الأخرى، فإن هذا يؤدي إلى الحاجة إلى عرض جميع عقد vdom بشكل متكرر إلى dom في وقت واحد دون مقاطعة.
ماذا يحدث إذا تمت مقاطعته؟ نظرًا لعدم تسجيل العقدة الأصلية والعقدة الشقيقة، يمكننا فقط الاستمرار في معالجة العقد الفرعية، لكن لا يمكننا معالجة الأجزاء الأخرى من vdom.
لهذا السبب قدمت React هذا النوع من بنية الألياف، والتي تحتوي على مراجع مثل إرجاع العقدة الأصلية، والعقدة الفرعية، والعقدة الشقيقة، وما إلى ذلك، والتي يمكن مقاطعتها، لأنه يمكن العثور على جميع العقد غير المعالجة بعد المقاطعة والاسترداد.
هيكل العقدة الليفية هو كما يلي:
يمكن مقاطعة هذه العملية، وبطبيعة الحال يمكن جدولتها، وهي عملية جدولة.
لذلك، تنقسم بنية الألياف إلى ثلاث مراحل: الجدول الزمني، والتوفيق (تحويل vdom إلى ألياف)، والالتزام (التحديث إلى dom).
يمكن استخدام الخطافات في المكونات الوظيفية للوصول إلى بعض القيم، ويتم تخزين هذه القيم على العقدة الليفية.
على سبيل المثال، يتم استخدام 6 خطافات في مكون الوظيفة هذا:
ثم هناك قائمة مرتبطة بـ MemorizedState مكونة من 6 عناصر على العقدة الليفية المقابلة:
متسلسل بواسطة التالي:
يمكن للخطافات المختلفة الوصول إلى القيم الموجودة في عناصر مختلفة من القائمة المرتبطة بالحالة المحفوظة. وهذا هو مبدأ خطافات التفاعل.
تحتوي هذه القائمة المرتبطة على مرحلة إنشاء ومرحلة تحديث، لذلك ستجد أن التنفيذ النهائي لـ useXxx مقسم إلى mountXxx وupdateXxx:
تتمثل مرحلة التثبيت هنا في إنشاء عقد ربط وتجميعها في قائمة مرتبطة:
سيتم ربط قائمة الخطاف المرتبطة التي تم إنشاؤها بسمة memorizedState الخاصة بعقدة الألياف.
عند التحديث، يمكنك بشكل طبيعي استرداد قائمة الخطاف هذه من عقدة الألياف:
بهذه الطريقة، في عروض متعددة، يمكن لواجهة برمجة التطبيقات useXxx العثور على الحالة المحفوظة المقابلة على العقدة الليفية.
هذا هو مبدأ الخطافات التفاعلية. يمكنك أن ترى أنه يخزن الخطاف على العقدة الليفية.
إذن ما هو الفرق مع preact؟
Preact هو إطار عمل خفيف الوزن ومتوافق مع تعليمات برمجية التفاعلية، وهو يدعم مكونات الفئة ومكونات الوظائف، بالإضافة إلى ميزات التفاعل مثل الخطافات. ومع ذلك، فإنه لا يطبق بنية الألياف.
لأنه يأخذ في الاعتبار الحجم النهائي (3 كيلو بايت فقط)، وليس الأداء النهائي.
لقد علمنا للتو أن رد الفعل يخزن قائمة الخطافات على عقدة الألياف، إذا لم يكن لدى preact عقدة ليفية، فأين سيتم تخزين قائمة الخطافات؟
في الواقع، من السهل الاعتقاد بأن الألياف تقوم فقط بتعديل vdom لتحسين الأداء، ولا يوجد فرق أساسي عن vdom، فهل يمكننا فقط تخزين الخطاف على vdom؟
في الواقع، يضع preact قائمة الخطاف على vdom.
على سبيل المثال، يحتوي مكون الوظيفة هذا على 4 خطافات:
تنفيذه هو الوصول إلى الخطاف المقابل على vdom:
لا يقسم الخطاف إلى مرحلتين، التثبيت والتحديث، مثل التفاعل، ولكنه يدمجهما معًا للمعالجة.
كما هو موضح في الشكل، يقوم بتخزين الخطافات في مصفوفة المكون .__hooks والوصول إليها من خلال الاشتراكات.
هذا المكون هو سمة على vdom:
أي أنه يتم تخزين قيمة الخطافات في مصفوفة vnode._component._hooks.
قارن الاختلافات بين رد الفعل وpreact في تنفيذ الخطافات:
في رد الفعل، يتم تخزين قائمة الخطاف على سمة FiberNode.memorizedState، وفي preact، يتم تخزين قائمة الخطاف على سمة vnode._component._hooks
وقائمة الخطاف في رد الفعل متسلسلة إلى التالي، وفي preact، القائمة المرتبطة بالربط عبارة عن مصفوفة.
تفصل React بين إنشاء وتحديث القائمة المرتبطة بالربط
لا يعتمد تنفيذ الخطافات على الألياف، بل يحتاج فقط إلى العثور على مكان لتخزين بيانات الخطاف المقابلة للمكون، وطالما أنه يمكن استرجاعها أثناء العرض، فلا يهم مكان تخزينها.
نظرًا لأن vdom والألياف وتجسيد المكونات مرتبطة ارتباطًا وثيقًا، يتم تخزينها في هذه الهياكل.
على سبيل المثال، عندما ينفذ رد فعل ssr الخطافات، فهو غير موجود على الألياف ولا على vdom:
في الواقع، بالإضافة إلى csr، يمكن لحزمة رد فعل dom أيضًا القيام بـ ssr:
استخدم طريقة العرض لـ رد فعل- دوم عند المسؤولية الاجتماعية للشركات:
عند ssr، استخدم طريقة renderToString أو طريقة renderToStream الخاصة بـ React-dom/server:
هل تعتقد أنه سيتم تحويل vdom إلى ألياف خلال ssr؟
بالتأكيد لا. إن Fiber عبارة عن بنية تم تقديمها لتحسين أداء العرض عند التشغيل في المتصفح، وجعل العمليات الحسابية غير قابلة للمقاطعة، وإجراء العمليات الحسابية في حالة الخمول.
العرض من جانب الخادم بطبيعة الحال لا يتطلب الألياف.
إذا لم تكن هناك حاجة للألياف، فأين يتم تخزين قائمة الخطافات؟ فدوم؟
يمكن بالفعل وضعه في vdom، لكنه ليس كذلك.
على سبيل المثال، استخدم خطافات Ref:
إنها قائمة مرتبطة متسلسلة مع التالي بدءًا من firstWorkInProgressHook.
وfirstWorkInProgressHook هي أول عقدة ربط تم إنشاؤها باستخدام createHook:
لم يتم تركيبه على vdom.
لماذا؟
نظرًا لأن ssr يحتاج إلى العرض مرة واحدة فقط ولا يحتاج إلى التحديث، فلا داعي لتعليقه على vdom.
ما عليك سوى مسح قائمة الارتباطات في كل مرة تنتهي فيها من معالجة الخطافات الخاصة بكل مكون:
ولذلك، عند استخدام رد فعل ssr، توجد الخطافات في المتغيرات العامة.
قارن الفرق بين مبادئ تنفيذ الخطافات في رد فعل csr وssr:
في csr، سيتم إنشاء الألياف من vdom، والتي تُستخدم لجعل العرض قابلاً للمقاطعة وتحسين الأداء من خلال جدولة الخمول، ولكن في ssr، لن يتم عرضها مباشرة بواسطة عند استخدام
vdom، يتم حفظ الخطافات في العقدة الليفية، بينما عند استخدام ssr، يتم وضعها مباشرة على المتغيرات العامة، ويتم مسحها بعد معالجة كل مكون. نظرًا لأنه لن يتم استخدام CSR مرة أخرى
، فسيتم تقسيم إنشاء الخطافات وتحديثها إلى مرحلتين: التثبيت والتحديث، بينما ستتم معالجة SSR مرة واحدة فقط، ومرحلة الإنشاء فقط
هي في الواقع ليست معقدة أي أنه في سياق معين قم بتخزين قائمة مرتبطة في القائمة المرتبطة، ثم تصل واجهة برمجة تطبيقات الخطافات إلى البيانات المقابلة من عناصر مختلفة في القائمة المرتبطة لإكمال المنطق الخاص بها. يمكن أن يكون هذا السياق vdom أو أليافًا أو حتى متغيرًا عالميًا.
ومع ذلك، فإن فكرة الخطافات لا تزال تحظى بشعبية كبيرة، حيث قدم إطار العمل من جانب الخادم الذي أنتجته تاوباو فكرة الخطافات:
بواسطة إطار عمل Node.js:
بطبيعة الحال، لا يحتوي إطار عمل جانب الخادم على هياكل مثل vdom والألياف، لكن فكرة الخطافات لا تعتمد عليها لتنفيذ واجهة برمجة تطبيقات الخطافات، ما عليك سوى وضع قائمة مرتبطة في سياق معين.
تطبق Midway واجهة برمجة تطبيقات مشابهة لخطافات التفاعل:
لم أبحث على وجه التحديد عن مكان وجود قائمة الخطافات، لكننا أتقننا بالفعل مبدأ تنفيذ الخطافات، وطالما أن هناك سياقًا لتخزين قائمة الخطافات، فيمكن أن تكون في أي مكان.
الخطافات التفاعلية هي ميزة ظهرت بعد بنية الألياف التفاعلية، يعتقد الكثير من الناس خطأً أنه يجب تنفيذ الخطافات باستخدام الألياف. لقد نظرنا إلى تنفيذ الخطافات في التفاعلات، والتفاعلات المسبقة، والتفاعلات ssr، وفي منتصف الطريق على التوالي، ووجدنا ذلك ليس هذا هو الحال:
التطبيقات
سيكون جيدًا، فهل يجب أن تعتمد خطافات التفاعل على الألياف لتنفيذها؟
من الواضح أنه لا، يمكن استخدامه مع الألياف أو vdom أو المتغيرات العامة أو حتى أي سياق.