ما هو Redux: دليل المصمم
نشرت: 2022-03-10هل سمعت عن Redux؟ ما هذا؟ لا غوغل ، من فضلك!
- "أشياء رائعة للخلفية."
- "لقد سمعت عن ذلك ، لكنني لست على علم بما هو عليه. ربما يكون إطار عمل React؟ "
- "طريقة أفضل لتخزين وإدارة الحالات في تطبيق React."
لقد طرحت هذا السؤال على أكثر من 40 مصممًا. ما سبق هو إجاباتهم النموذجية. يدرك الكثير منهم أن Redux تعمل مع React ووظيفتها هي "إدارة الحالة".
لكن هل تعرف ما تعنيه "إدارة الدولة" حقًا؟ هل تعلم أن القوة الحقيقية لـ Redux تتجاوز إدارة الدولة؟ هل تعلم أن Redux لا يتطلب بالضرورة عمل React ؟ هل تريد الانضمام إلى مناقشة فريقك (أو على الأقل محادثات الغداء) حول استخدام Redux؟ هل تريد التصميم مع فهم كيفية عمل Redux؟
بمساعدة هذه المقالة ، أود أن أعرض لك صورة كاملة عن Redux : ما الذي يمكنه فعله ، ولماذا يفعل الأشياء ، وما هي الجوانب السلبية ، ومتى يتم استخدامه ، وكيف يرتبط بالتصميم.
هدفي هو مساعدة المصممين مثلك. حتى لو لم تكن قد كتبت سطرًا واحدًا من التعليمات البرمجية من قبل ، أعتقد أنه لا يزال من الممكن والمفيد (والممتع) فهم Redux. توقع لغة إنجليزية بسيطة ورسومات الشعار المبتكرة - بدون كود أو محادثات مجردة.
جاهز للركوب؟
ما هو Redux؟
على مستوى عالٍ للغاية ، تعد Redux أداة يستخدمها المطورون لتسهيل حياتهم. كما قد سمع الكثير منكم ، فإن وظيفتها هي "إدارة الدولة". سأشرح ما تعنيه إدارة الدولة لاحقًا. في هذه المرحلة ، سأترك لك هذه الصورة:

لماذا يجب أن تهتم؟
تتعلق Redux بالأعمال الداخلية للتطبيق أكثر من كونها تتعلق بالشكل والمظهر. إنها أداة معقدة إلى حد ما مع منحنى تعليمي حاد. هل هذا يعني أننا كمصممين يجب أن نبتعد عنها؟
لا ، أعتقد أننا يجب أن نتبناه. مصمم السيارة يجب أن يفهم ما هو المحرك ، أليس كذلك؟ لتصميم واجهات التطبيق بنجاح ، يجب أن يكون لدى المصممين أيضًا معرفة قوية بالأشياء الموجودة تحت الغطاء . يجب أن نتعرف على ما يمكن أن يفعله ، وأن نفهم سبب استخدامه للمطورين ، وأن نكون على دراية بمزاياها وآثارها.
"التصميم لا يقتصر فقط على الشكل والمظهر. التصميم هو كيف يعمل."
- ستيف جوبز
ما الذي يمكن أن تفعله Redux؟
يستخدم العديد من الأشخاص Redux لإدارة الحالة في تطبيقات React. إنها حالة الاستخدام الأكثر شيوعًا في البرية وتعمل Redux على تحسين الجوانب التي لا تعمل فيها React جيدًا (حتى الآن).
ومع ذلك ، سترى قريبًا أن القوة الحقيقية لـ Redux تتجاوز ذلك. لنبدأ بتعلم ما تعنيه إدارة الدولة حقًا.
إدارة الدولة
إذا لم تكن متأكدًا مما تعنيه هذه "الحالة" ، فلنستبدلها بمصطلح أكثر عمومية: "البيانات". الدولة هي البيانات التي تتغير من وقت لآخر . تحدد الحالة ما يتم عرضه على واجهة المستخدم.
ماذا تعني إدارة الدولة؟ بشكل عام ، هناك ثلاثة جوانب من البيانات نحتاج إلى إدارتها في التطبيق:
- إحضار وتخزين البيانات
- تعيين البيانات لعناصر واجهة المستخدم
- تغيير البيانات
لنفترض أننا نبني صفحة لقطة Dribbble. ما هي البيانات التي نريد عرضها على الصفحة؟ وهي تشمل صورة الملف الشخصي للمؤلف واسمه وصورة GIF المتحركة وعدد القلوب والتعليقات وما إلى ذلك.

أولاً ، نحتاج إلى جلب كل هذه البيانات من خادم في السحابة ووضعها في مكان ما. بعد ذلك ، نحتاج إلى عرض البيانات بالفعل. نحتاج إلى تعيين أجزاء من هذه البيانات لعناصر واجهة المستخدم المقابلة التي تمثل ما نراه بالفعل في المتصفح. على سبيل المثال ، نقوم بتعيين عنوان URL لصورة الملف الشخصي إلى سمة src
لعلامة HTML img
:
<img src='https://url/to/profile_photo'>
أخيرًا ، نحتاج إلى التعامل مع التغييرات التي تطرأ على البيانات. على سبيل المثال ، إذا أضاف مستخدم تعليقًا جديدًا إلى لقطة Dribbble ، أو أضاف نجمة ، فنحن بحاجة إلى تحديث HTML وفقًا لذلك.
يعد تنسيق هذه الجوانب الثلاثة للحالة جزءًا كبيرًا في تطوير الواجهة الأمامية ، ولدى React درجات مختلفة من الدعم لهذه المهمة. في بعض الأحيان ، تعمل الأداة المدمجة في React بشكل جيد. ولكن مع ازدياد تعقيد التطبيق ، قد تصبح حالته أكثر صعوبة في التعامل مع React وحدها. لهذا السبب يبدأ الكثير من الناس في استخدام Redux كبديل.
إحضار وتخزين البيانات
في React ، نقسم واجهة المستخدم إلى مكونات. يمكن تقسيم كل من هذه المكونات إلى مكونات أصغر (انظر "ما هي React؟").

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

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

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

هذا الأسلوب أكثر كفاءة من الطريقة الساذجة لجلب البيانات من كل مكون. ولكن كيف تمرر شوتويل المكونات إلى الطهاة الآخرين؟ كيف تمرر البيانات إلى المكونات التي تعرض عناصر HTML بالفعل؟ نقوم بتمرير البيانات من المكونات الخارجية إلى المكونات الداخلية مثل العصا في مرحل ، على طول الطريق حتى تصل البيانات إلى الوجهة.
على سبيل المثال ، يجب أن يتم تمرير عنوان URL للصورة الرمزية للمؤلف من "Shot" إلى "ShotDetail" و "Title" وأخيراً إلى علامة <img>
. إذا كان طهاتنا يعيشون في شقة ، فستبدو حقًا كما يلي:

لتسليم البيانات إلى الوجهة ، سيتعين علينا إشراك جميع المكونات الموجودة على المسار ، حتى لو لم تكن بحاجة إلى البيانات على الإطلاق. سيكون الأمر مزعجًا حقًا إذا كان هناك العديد من الطوابق!
ماذا لو قام المتجر الكبير بالتسليم من الباب إلى الباب؟ مع Redux 1 ، يمكننا توصيل أي بيانات بأي مكون ، دون التأثير على المكونات الأخرى على الإطلاق ، مثل:
1 لكي أكون دقيقًا تمامًا ، إنها مكتبة أخرى تسمى react-redux
التي تسلم البيانات إلى مكونات React ، وليس Redux نفسها. ولكن نظرًا لأن رد الفعل والإحياء يقوم فقط بالسباكة ويستخدم الأشخاص دائمًا ميزة Redux والتفاعل وإعادة الإحياء معًا ، أعتقد أنه من الجيد تضمين هذا كأحد فوائد Redux.

ملاحظة : في الإصدار الأخير من React (16.3) ، توجد واجهة برمجة تطبيقات جديدة "للسياق" تؤدي نفس الوظيفة تقريبًا من حيث توصيل البيانات بالمكونات. لذا ، إذا كان هذا هو السبب الوحيد الذي يجعل فريقك يستخدم Redux ، ففكر بجدية في الترقية إلى React 16.3! تحقق من الوثيقة الرسمية لمزيد من المعلومات (تحذير: الكثير من التعليمات البرمجية في المستقبل).
تغيير البيانات
في بعض الأحيان ، قد يكون منطق تحديث البيانات في التطبيق معقدًا إلى حد ما. قد يتضمن خطوات متعددة تعتمد على بعضها البعض. قد نحتاج إلى انتظار الردود من خوادم متعددة قبل تحديث حالة التطبيق. قد نحتاج إلى تحديث العديد من الأماكن في الولاية في أوقات مختلفة وفي ظل ظروف مختلفة.
قد يكون الأمر مربكًا إذا لم يكن لدينا هيكل جيد لكل هذا المنطق. سيكون من الصعب فهم الكود والمحافظة عليه.
إعادة تسمح لنا بفرق تسد . يوفر طريقة قياسية لتقسيم منطق تحديث البيانات إلى "مخفضات" صغيرة. تعمل هذه المخفضات بانسجام معًا لإكمال إجراء معقد.


راقب التطور الأخير لـ React. كما هو الحال مع واجهة برمجة التطبيقات "Context" ، قد تكون هناك واجهة برمجة تطبيقات "setState" جديدة في إصدار مستقبلي من React. سيسهل تقسيم منطق التحديث المعقد إلى أجزاء أصغر. بمجرد أن تصبح واجهة برمجة التطبيقات الجديدة هذه متاحة ، من المحتمل أنك لن تحتاج إلى Redux بعد الآن لإدارة هذا الجانب من إدارة الحالة.
القوة الحقيقية للإحياء
حتى الآن ، يبدو أن Redux هو مجرد أداة مساعدة لـ React. يستخدم الناس Redux لتحسين الجوانب التي لا تعمل React بشكل جيد (حتى الآن). لكن React يلحق بالركب بسرعة! في الواقع ، انضم دان أبراموف ، مبتكر Redux ، إلى فريق React الأساسي في Facebook منذ عامين. لقد كانوا مشغولين في العمل على التحسينات المذكورة أعلاه على React: واجهة برمجة تطبيقات السياق (تم إصدارها في 16.3) ، وجلب بيانات API أفضل (تم عرضه في فبراير 2018) ، وواجهة برمجة تطبيقات setState أفضل وما إلى ذلك.
هل سيجعل Redux قديمًا؟
خمين ما؟ لم أظهر لك القوة الحقيقية لـ Redux حتى الآن!

يجبر Redux المطورين على اتباع بعض القواعد الصارمة ، والتي تجلب Redux الكثير من القوة (نعم ، قوة الانضباط!):
- يجب وصف جميع البيانات (حالة التطبيق) بنص واضح. يجب أن تكون قادرًا على تدوين جميع البيانات بقلم على الورق.
- يجب وصف كل إجراء (تغيير البيانات) بنص واضح. يجب عليك كتابة ما ستفعله قبل تغيير أي شيء. لا يمكنك تغيير البيانات دون ترك علامة. هذه العملية تسمى "إرسال عمل" في Redux العامية.
- يجب أن تتصرف الكود الذي يغير البيانات مثل صيغة الرياضيات. يجب أن ترجع نفس النتيجة مع إعطاء نفس المدخلات. دائمًا ما يكون مربع 4 هو 16 بغض النظر عن عدد مرات تشغيله.
عندما تتبع هذه القواعد لإنشاء التطبيقات ، يحدث السحر. إنه يتيح الكثير من الميزات الرائعة التي يصعب تنفيذها أو تكون باهظة الثمن. وهنا بعض الأمثلة. 2
2 لقد جمعت هذه الأمثلة من منشور دان أبراموف "قد لا تحتاج إلى إعادة تشغيل" و "سلسلة أسئلة رد الفعل للمبتدئين".
التراجع عن إعادته
تتطلب ميزة التراجع / الإعادة الشائعة تخطيطًا على مستوى النظام. نظرًا لأن التراجع / الإعادة يحتاج إلى تسجيل وإعادة كل تغيير فردي للبيانات في التطبيق ، يجب أن تأخذ ذلك في الاعتبار في البنية منذ البداية. إذا تم ذلك كفكرة لاحقة ، فستتطلب تغيير الكثير من الملفات وهي وصفة لأخطاء لا حصر لها.

نظرًا لأن Redux يتطلب وصف كل إجراء بنص واضح ، فإن دعم التراجع / الإعادة يكاد يكون مجانًا. تعليمات كيفية تنفيذ التراجع / الإعادة مع احتواء Redux في صفحة بسيطة.
بيئة العمل المشترك
إذا كنت تنشئ تطبيقًا مشابهًا لمُحرر مستندات Google حيث يعمل العديد من المستخدمين معًا في مهمة معقدة ، ففكر في استخدام Redux. من المحتمل أن تقوم بالكثير من رفع الأثقال من أجلك.

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

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

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

إذا قمت بإنشاء لعبة باستخدام Redux ، فستحتاج فقط إلى سطرين آخرين من التعليمات البرمجية لحفظ / تحميل تقدم اللعبة ، دون تغيير باقي الكود.
أنظمة قابلة للتوسيع حقًا
باستخدام Redux ، يجب "إرسال" إجراء لتحديث أي بيانات في التطبيق. يجعل هذا التقييد من الممكن ربط كل جوانب ما يحدث في التطبيق تقريبًا.
يمكنك إنشاء تطبيقات قابلة للتوسيع حقًا حيث يمكن للمستخدم تخصيص كل وظيفة. على سبيل المثال ، تحقق من Hyper ، وهو تطبيق طرفي تم إنشاؤه باستخدام Redux. يضيف ملحق "hyperpower" الرشات إلى المؤشر ويهز النافذة. كيف تحب هذا الوضع "المبهر"؟ (ربما لا يكون مفيدًا بشكل رهيب ولكنه كافٍ لإقناع المستخدمين)

تصحيح أخطاء السفر عبر الزمن
ماذا عن القدرة على السفر في الوقت المناسب عند تصحيح أخطاء التطبيق؟ يمكنك تشغيل التطبيق أو إرجاعه أو إعادة توجيهه عدة مرات للعثور على المكان المحدد عند حدوث الخطأ وإصلاح الخطأ وإعادة التشغيل للتأكيد.
Redux يجعل حلم المطورين هذا حقيقة. يتيح لك Redux DevTools معالجة تقدم تطبيق قيد التشغيل كفيديو على YouTube - عن طريق سحب شريط التمرير!
كيف يعمل؟ هل تتذكر القواعد الثلاث الصارمة التي يفرضها Redux؟ هذه هي الخلطة السرية للسحر.

تقارير الأخطاء الآلية
تخيل هذا: وجد المستخدم شيئًا خاطئًا في تطبيقك ويريد الإبلاغ عن الخطأ. تتذكر بشق الأنفس وتصف ما فعلته. ثم يحاول أحد المطورين اتباع الخطوات يدويًا لمعرفة ما إذا كان الخطأ قد حدث مرة أخرى. قد يكون تقرير الخطأ غامضًا أو غير دقيق. يواجه المطور صعوبة في العثور على مكان الخطأ.
الآن ، ماذا عن هذا. ينقر المستخدم على زر "إبلاغ عن خطأ". يرسل النظام تلقائيًا ما فعلته إلى المطور. ينقر المطور على زر "إعادة تشغيل الخطأ" ويراقب كيف يحدث هذا الخطأ بالضبط. تم سحق الحشرة على الفور ، الجميع سعداء!
هذا هو بالضبط ما سيحدث إذا كنت تستخدم Redux Bug Reporter. كيف يعمل؟ قيود إعادة الإنتاج تصنع العجائب.

سلبيات الإحياء
القواعد الرئيسية الثلاثة التي يفرضها Redux هي سيف ذو حدين. إنها تتيح ميزات قوية ، ولكنها تسبب في نفس الوقت جوانب سلبية لا مفر منها.
منحنى التعلم حاد
يحتوي Redux على منحنى تعليمي حاد نسبيًا. يستغرق فهم أنماطها وتذكرها والتعود عليها وقتًا. لا يُنصح بتعلم Redux و React في نفس الوقت إذا كان كلاهما جديدًا بالنسبة لك.
كود "Boilerplate"
في كثير من الحالات ، يعني استخدام Redux كتابة المزيد من التعليمات البرمجية. غالبًا ما يكون مطلوبًا لمس عدة ملفات للحصول على ميزة بسيطة تعمل. لقد اشتكى الناس من الكود "المعياري" الذي يتعين عليهم كتابته باستخدام Redux.
أعلم أن هذا يبدو متناقضًا. ألم أقول إن Redux يجعل من الممكن تنفيذ ميزات بأدنى حد من التعليمات البرمجية ؟ هذا يشبه إلى حد ما استخدام غسالة الصحون. أولاً ، عليك قضاء الوقت في ترتيب الأطباق بعناية في صفوف. حتى ذلك الحين ، سترى فوائد غسالة الأطباق: توفير الوقت الفعلي لتنظيف الأطباق وتعقيم الأطباق وما إلى ذلك. عليك أن تقرر ما إذا كان وقت التحضير يستحق كل هذا العناء!
عقوبة الأداء
يمكن أن يكون لـ Redux أيضًا تأثير على الأداء بسبب القيود التي يفرضها. يضيف القليل من الحمل كلما تغيرت البيانات. في معظم الحالات ، ليست مشكلة كبيرة ، والتباطؤ ليس ملحوظًا. ومع ذلك ، عندما يكون هناك قدر كبير من البيانات في المتجر وعندما تتغير البيانات بشكل متكرر (على سبيل المثال عندما يكتب المستخدم بسرعة على جهاز محمول) ، فقد تصبح واجهة المستخدم بطيئة نتيجة لذلك.
المكافأة: الإحياء ليس فقط للتفاعل
هناك اعتقاد خاطئ شائع أن Redux مخصص لـ React فقط. يبدو أن Redux لا يمكنه فعل أي شيء بدون رد فعل. في الواقع ، يُكمل Redux React بعدة طرق مهمة ، كما ناقشنا سابقًا. إنها حالة الاستخدام الأكثر شيوعًا.
ومع ذلك ، في الواقع ، يمكن أن يعمل Redux مع أي أطر أمامية ، مثل Angular أو Ember.js أو حتى jQuery أو حتى Vanilla JavaScript. جرب البحث في Google ، ستجد هذا ، هذا ، هذا أو حتى هذا. تنطبق الأفكار العامة لـ Redux في أي مكان!
طالما أنك تستخدم Redux بحكمة ، يمكنك الحصول على فوائدها في العديد من المواقف - ليس فقط في تطبيق React.

خاتمة
مثل أي أداة ، تقدم Redux مقايضة. إنه يتيح ميزات قوية ولكن له أيضًا عيوب لا مفر منها. تتمثل مهمة فريق التطوير في تقييم ما إذا كانت المقايضة تستحق العناء واتخاذ قرار واعي.
بصفتنا مصممين ، إذا فهمنا مزايا وعيوب Redux ، فسنكون قادرين على المساهمة في اتخاذ هذا القرار من منظور التصميم. على سبيل المثال ، ربما يمكننا تصميم واجهة المستخدم للتخفيف من تأثير الأداء المحتمل؟ ربما يمكننا أن ندعو إلى تضمين ميزات التراجع / الإعادة لإزالة عبء كبير من مربعات حوار التأكيد؟ ربما يمكننا اقتراح واجهة مستخدم متفائلة لأنها تحسن تجربة المستخدم بتكلفة منخفضة نسبيًا؟
افهم مزايا وقيود التكنولوجيا ، وصمم وفقًا لذلك. أعتقد أن هذا ما قصده ستيف جوبز بعبارة "التصميم هو كيف يعمل."