إعادة · مقدمة

نشرت: 2022-03-10
ملخص سريع ↬ تعد Redux واحدة من أهم المكتبات في تطوير الواجهة الأمامية هذه الأيام. ومع ذلك ، يحتار الكثير من الناس حول ماهيته وما هي فوائده. كما تنص الوثائق ، فإن Redux عبارة عن حاوية حالة يمكن التنبؤ بها لتطبيقات JavaScript . لإعادة صياغة ذلك ، إنها بنية تدفق بيانات تطبيق ، بدلاً من مكتبة تقليدية أو إطار عمل مثل Underscore.js و AngularJS.

تعد Redux واحدة من أكثر المكتبات شيوعًا في تطوير الواجهة الأمامية هذه الأيام. ومع ذلك ، يحتار الكثير من الناس حول ماهيته وما هي فوائده.

كما تنص الوثائق ، فإن Redux عبارة عن حاوية حالة يمكن التنبؤ بها لتطبيقات JavaScript. لإعادة صياغة ذلك ، إنها بنية تدفق بيانات تطبيق ، بدلاً من مكتبة تقليدية أو إطار عمل مثل Underscore.js و AngularJS.

مزيد من القراءة على SmashingMag

  • لماذا يجب أن تفكر في React Native لتطبيق الجوال الخاص بك
  • اختبار التشغيل الآلي للتطبيقات والألعاب والويب المحمول
  • عرض من جانب الخادم باستخدام React و Node و Express
  • ملاحظات حول إمكانية الوصول التي يقدمها العميل

تم إنشاء Redux بواسطة Dan Abramov في يونيو 2015 تقريبًا. وقد استوحى من Flux من Facebook ولغة البرمجة الوظيفية Elm. اكتسب Redux شهرة كبيرة بسرعة كبيرة بسبب بساطته وصغر حجمه (2 كيلوبايت فقط) ووثائقه الرائعة. إذا كنت ترغب في معرفة كيفية عمل Redux داخليًا والتعمق في المكتبة ، ففكر في الاطلاع على دورة Dan المجانية.

المزيد بعد القفز! أكمل القراءة أدناه ↓

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

كيف تختلف عن MVC والتدفق؟

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

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

فوائد الإحياء

قد تسأل ، "لماذا أحتاج إلى استخدام Redux؟" سؤال رائع. هناك بعض الفوائد لاستخدام Redux في تطبيقك التالي:

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

البرمجة الوظيفية

كما ذكرنا ، تم بناء Redux على رأس مفاهيم البرمجة الوظيفية. إن فهم هذه المفاهيم مهم جدًا لفهم كيف ولماذا يعمل Redux بالطريقة التي يعمل بها. لنراجع المفاهيم الأساسية للبرمجة الوظيفية:

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

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

01- برمجة-وظيفية-اختيار-معاينة
مثال على البرمجة الوظيفية (الصورة: تانيا باشوك) (عرض النسخة الكبيرة)

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

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

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

أين يمكن استخدام Redux؟

يربط معظم المطورين Redux بـ React ، ولكن يمكن استخدامه مع أي مكتبة عرض أخرى. على سبيل المثال ، يمكنك استخدام Redux مع AngularJS و Vue.js و Polymer و Ember و Backbone.js و Meteor. ومع ذلك ، لا تزال Redux plus React هي التركيبة الأكثر شيوعًا. تأكد من تعلم React بالترتيب الصحيح: أفضل دليل هو Pete Hunt's ، وهو مفيد جدًا للمطورين الذين بدأوا في React والذين غارقون في كل ما يحدث في النظام البيئي. يُعد إجهاد JavaScript مصدر قلق مشروع بين مطوري الواجهة الأمامية ، سواء الجدد أو المتمرسين ، لذا خذ الوقت الكافي لتعلم React أو Redux بالطريقة الصحيحة بالترتيب الصحيح.

أحد الأسباب التي تجعل Redux رائعًا هو نظامه البيئي. يتوفر الكثير من المقالات والبرامج التعليمية والبرمجيات الوسيطة والأدوات والنماذج المعيارية. أنا شخصياً أستخدم نموذج David Zukowski المعياري لأنه يحتوي على كل ما يحتاجه المرء لبناء تطبيق JavaScript ، باستخدام React و Redux و React Router. كلمة تحذير: حاول ألا تستخدم Boilerplates and starter kits عند تعلم أطر عمل جديدة مثل React و Redux. سيجعل الأمر أكثر إرباكًا ، لأنك لن تفهم كيف يعمل كل شيء معًا. تعلمها أولاً وأنشئ تطبيقًا بسيطًا للغاية ، من الناحية المثالية كمشروع جانبي ، ثم استخدم النماذج المعيارية لتطبيقات الإنتاج لتوفير الوقت.

أجزاء البناء من الإحياء

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

02 معاينة إعادة تدفق البيانات
إعادة تدفق البيانات (الصورة: تانيا باشوك) (عرض نسخة كبيرة)

دعونا نناقش ما يفعله كل منهما.

أجراءات

باختصار ، الأفعال هي أحداث. ترسل الإجراءات البيانات من التطبيق (تفاعلات المستخدم والأحداث الداخلية مثل مكالمات واجهة برمجة التطبيقات وعمليات إرسال النماذج) إلى المتجر. يحصل المتجر على المعلومات فقط من الإجراءات. الإجراءات الداخلية هي كائنات JavaScript بسيطة لها خاصية type (ثابتة عادةً) ، تصف نوع الإجراء وحمولة المعلومات التي يتم إرسالها إلى المتجر.

 { type: LOGIN_FORM_SUBMIT, payload: {username: 'alex', password: '123456'} }

يتم إنشاء الإجراءات مع المبدعين. هذا يبدو واضحًا ، أعرف. إنها مجرد وظائف تعيد الإجراءات.

 function authUser(form) { return { type: LOGIN_FORM_SUBMIT, payload: form } }

إذن ، فإن استدعاء الإجراءات في أي مكان في التطبيق أمر سهل للغاية. استخدم طريقة dispatch ، مثل:

 dispatch(authUser(form));

مخفضات

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

 function handleAuth(state, action) { return _.assign({}, state, { auth: action.payload }); }

بالنسبة للتطبيقات الأكثر تعقيدًا ، من الممكن استخدام الأداة المساعدة combineReducers() التي يوفرها Redux (بالفعل موصى بها). فهو يجمع بين جميع مخفضات التطبيق في مخفض فهرس واحد. كل مخفض مسؤول عن الجزء الخاص به من حالة التطبيق ، ومعلمة الحالة مختلفة لكل مخفض. الأداة المساعدة combineReducers() تجعل صيانة بنية الملف أسهل بكثير.

إذا غيّر كائن (حالة) بعض القيم فقط ، فإن Redux ينشئ كائنًا جديدًا ، وستشير القيم التي لم تتغير إلى الكائن القديم وسيتم إنشاء القيم الجديدة فقط. هذا رائع للأداء. لجعله أكثر كفاءة ، يمكنك إضافة Immutable.js.

 const rootReducer = combineReducers({ handleAuth: handleAuth, editProfile: editProfile, changePassword: changePassword });

متجر

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

 import { createStore } from 'redux'; let store = createStore(rootReducer); let authInfo = {username: 'alex', password: '123456'}; store.dispatch(authUser(authInfo));

أدوات المطور ، السفر عبر الزمن وإعادة التحميل السريع

لتسهيل العمل مع Redux ، خاصة عند العمل مع تطبيق واسع النطاق ، أوصي باستخدام Redux DevTools. إنه مفيد بشكل لا يصدق ، حيث يُظهر تغييرات الحالة بمرور الوقت ، والتغييرات في الوقت الفعلي ، والإجراءات ، والحالة الحالية. هذا يوفر عليك الوقت والجهد عن طريق تجنب الإجراءات والحالة الحالية لـ console.log

03-redux-dev-tools-opt-Preview
Redux DevTools (عرض النسخة الكبيرة)

لدى Redux تنفيذ مختلف قليلاً للسفر عبر الزمن عن Flux. في Redux ، يمكنك العودة إلى حالة سابقة وحتى اتخاذ حالتك في اتجاه مختلف عن تلك النقطة فصاعدًا. تدعم Redux DevTools ميزات "السفر عبر الزمن" التالية في سير عمل Redux (فكر فيها كأوامر Git لحالتك):

  • إعادة التعيين: إعادة التعيين إلى الحالة التي تم إنشاء متجرك بها
  • العودة : يعود إلى آخر حالة ملتزمة
  • المسح : يزيل كل التصرفات المعطلة التي ربما أطلقت عن طريق الخطأ
  • الالتزام : يجعل الحالة الحالية هي الحالة الأولية

ميزة السفر عبر الزمن ليست فعالة في الإنتاج وهي مخصصة فقط للتطوير وتصحيح الأخطاء. الشيء نفسه ينطبق على DevTools.

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

بناء التطبيق

لاختتام هذا الدليل التمهيدي ، فلنقم ببناء تطبيق بسيط للغاية باستخدام Redux و React. لتسهيل متابعة الجميع ، سألتزم باستخدام JavaScript القديم البسيط ، باستخدام ECMAScript 2015 و 2016 بأقل قدر ممكن. سنواصل منطق تسجيل الدخول الذي بدأ سابقًا في هذا المنشور. لا يستخدم هذا المثال أي بيانات مباشرة ، لأن الغرض من هذا التطبيق هو إظهار كيفية إدارة Redux لحالة تطبيق بسيط للغاية. سنستخدم CodePen.

1. مكون رد الفعل

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

شاهد مقدمة القلم إلى Redux بواسطة Alex Bachuk (abachuk) على CodePen.

شاهد مقدمة القلم إلى Redux بواسطة Alex Bachuk (abachuk) على CodePen.

2. الأحداث والإجراءات

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

راجع مقدمة القلم إلى Redux - الخطوة 2. الأحداث والإجراءات التي قام بها Alex Bachuk (abachuk) على CodePen.

راجع مقدمة القلم إلى Redux - الخطوة 2. الأحداث والإجراءات التي قام بها Alex Bachuk (abachuk) على CodePen.

3. المخفضات

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

  1. الحالة الحالية (التي لها القيمة الافتراضية) ،
  2. الحدث.

انظر مقدمة القلم إلى Redux - الخطوة 3. المخفضات بواسطة Alex Bachuk (abachuk) على CodePen.

انظر مقدمة القلم إلى Redux - الخطوة 3. المخفضات بواسطة Alex Bachuk (abachuk) على CodePen.

4. عرض الحالة الحالية

الآن ، لدينا الحالة الأولية (القيمة الافتراضية في المخفض) ومكون React جاهز ، دعنا نرى كيف تبدو الحالة. أفضل ممارسة هي دفع الدولة إلى مكونات الأطفال. نظرًا لأن لدينا مكونًا واحدًا فقط ، فلنقم بتمرير حالة التطبيق كخاصية لمكونات auth . لجعل كل شيء يعمل معًا ، يتعين علينا تسجيل مستمع المتجر باستخدام التابع المساعد ReactDOM.render subscribe دالة وتمريرها إلى store.subscribe() :

راجع مقدمة القلم إلى Redux - الخطوة 4. عرض الحالة الحالية بواسطة Alex Bachuk (abachuk) على CodePen.

راجع مقدمة القلم إلى Redux - الخطوة 4. عرض الحالة الحالية بواسطة Alex Bachuk (abachuk) على CodePen.

5. تسجيل الدخول والخروج

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

راجع مقدمة القلم إلى Redux - الخطوة 5. تسجيل الدخول / تسجيل الخروج بواسطة Alex Bachuk (abachuk) على CodePen.

راجع مقدمة القلم إلى Redux - الخطوة 5. تسجيل الدخول / تسجيل الخروج بواسطة Alex Bachuk (abachuk) على CodePen.

خاتمة

يكتسب Redux زخمًا كل يوم. تم استخدامه من قبل العديد من الشركات (Uber ، Khan Academy ، Twitter) وفي العديد من المشاريع (Apollo ، WordPress 'Calypso) ، بنجاح في الإنتاج. قد يشتكي بعض المطورين من وجود الكثير من النفقات العامة. في معظم الحالات ، يلزم المزيد من التعليمات البرمجية لتنفيذ إجراءات بسيطة مثل نقرات الأزرار أو تغييرات بسيطة في واجهة المستخدم. Redux ليس مناسبًا تمامًا لكل شيء. يجب أن يكون هناك توازن. ربما لا يجب أن تكون الإجراءات البسيطة وتغييرات واجهة المستخدم جزءًا من متجر Redux ويمكن الحفاظ عليها على مستوى المكون.

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

اعتمادات صورة الصفحة الأولى: Lynn Fisher،lynnandtonic