دليل المبتدئين إلى Redux

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

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

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

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

ملخص الخطوات

  1. اكتب وظيفة المخفض
  2. إنشاء المتجر في مكون الجذر
  3. لف المكونات بالمكون ، وتمر في المتجر كدعم
  4. اكتب المكون
  5. حدد الإجراءات
  6. حدد الإرسال ، وأرفقه بالمكان الذي سيتم فيه تشغيل الإرساليات (أي مستمعي الأحداث ، إلخ)
  7. تحديد وظيفة mapStateToProps
  8. قم بتصدير وظيفة الاتصال ، وتمريرها في mapStateToProps و null كالوسيطتين وتمرير اسم المكون في الزوج الثاني من الأقواس

خطوات

1. اكتب وظيفة المخفض

وظيفة المخفض هي وظيفة تخبر المتجر بكيفية الاستجابة للإجراءات. ترجع الدالة الحالة الجديدة والمحدثة كلما تم إرسال إجراء. الحالة غير قابلة للتغيير (لا يمكن تغييرها) لذا يقوم المخفض دائمًا بإرجاع حالة جديدة. عادةً ما يستخدم المخفض عامل الانتشار لإدخال الحالة الحالية في كائن / مصفوفة جديدة وإلحاقها بها. الممارسة الشائعة هي استخدام جملة switch / case والتحقق من خاصية النوع للإجراء الذي تم تمريره. ثم اكتب الرمز الذي يحدّث الحالة لكل حالة.

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

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

يتم تمرير المخفض مع معلمتين: الحالة (هذه هي الحالة الكاملة الموجودة حاليًا في المتجر ، ونمنحها قيمة افتراضية إذا لم تكن الحالة موجودة بعد) والإجراء. نعيد الحالة في الحالة الافتراضية.

2. إنشاء المتجر في مكون الجذر

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

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

عادةً ما يتم إنشاء مثيل المتجر في جذر تطبيقك (مثل App.js). يتم تخزينه كمتغير ويتم تمرير المخفض كمعامل. يتم بعد ذلك تمرير المخزن كعنصر خاص إلى مكون الموفر.

نقوم بإنشاء مثيل لكائن متجرنا في المخفض الذي أنشأناه للتو.

3. لف المكونات مع المكون ، وتمر في المخزن كدعامة

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

نقوم بتغليف مكون Todo الذي سنقوم بصنعه باستخدام مكون المزود. نمر في المتجر الذي أنشأناه في الخطوة السابقة.

4. اكتب المكون

بعد ذلك ، نبدأ في كتابة مكون Todo الذي سيعرض عناصر المهام ويتفاعل مع متجر Redux.

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

5. تحديد الإجراءات

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

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

إذا كنت تتذكر رد المخفض الخاص بنا على نوعين من الإجراءات - "ADD_TODO" و "REMOVE_TODO". سنحدد هذه الإجراءات مع صانعي العمل لدينا. في الإجراء add_todo الخاص بنا ، سيعيد "ADD_TODO" كنوع وعنصر المهام التي نريد إضافتها إلى المتجر كقيمة (نحتاج إلى المتجر لإضافة عنصر todo هذا إلى الحالة حتى يتم تمريره هنا). في remove_todo نعيد "REMOVE_TODO" كنوع وفهرس عنصر المهام في المتجر كقيمة. سنحتاج هذا لإزالته من قائمة المهام.

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

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

6. حدد الإرسال ، وأرفقه بالمكان الذي سيتم فيه تشغيل الإرساليات (أي مستمعي الأحداث ، إلخ)

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

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

الزر الأول هو زر إضافة بسيط. سيقوم هذا الزر بإرسال الإجراء add_todo إلى المتجر. سيتم تمرير إدخال المستخدم الحالي كقيمة (هذا هو عنصر المهام الذي يلحقه المخفض بالحالة الجديدة). لاحظ أننا نسمي الإرسال كـ this.props.dispatch. إنه خارج نطاق هذا الدليل قليلاً لفهم كيف ولماذا يتم تمرير هذا كدعم للمكون. لذا اعلم فقط أنه كذلك ويمكننا تسميته على هذا النحو.

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

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

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

7. تحديد وظيفة mapStateToProps

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

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

تأخذ mapStateToProps الحالة بأكملها كمعامل ولا تأخذ منها إلا ما تحتاجه. هنا على الرغم من أن دولتنا تحتوي فقط على قائمة todos. نحتاج إلى هذه القائمة في مكون ToDo الخاص بنا ، وسنقوم بإرجاع الحالة بأكملها كخاصية تسمى todos.

كما ترون الآن ، لدينا وصول إلى قائمة todos بالكامل في الدعائم الخاصة بنا this.props.todos. هذه هي الطريقة التي تمكنا بها من تقديم جميع مهامنا في المثال السابق من خلال تعيينها.

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

8. قم بتصدير وظيفة الاتصال ، وتمريرها في mapStateToProps و null كالوسيطتين وتمرير اسم المكون في الزوج الثاني من الأقواس

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

connect(mapStateToProps, MapDispatchToProps)(YourComponent)

تقوم بتمرير map...ToPropsالوظيفتين إلى الاتصال ثم اسم المكون الخاص بك داخل الزوج الثاني من الأقواس. النمط المعتاد هو تصدير طريقة الاتصال بدلاً من المكون الخاص بك عندما تقوم بتصدير المكون الخاص بك في نهاية الملف. فمثلا:

export default connect(mapStateToProps, MapDispatchToProps)(YourComponent)

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

قد تتساءل من أين أتت وظيفة mapDispatchToProps هذه ولماذا لم نذكرها في أي مكان من قبل هنا. حسنًا ، نظرًا لأن هذا الدليل هو أبسط مثال على متجر Redux و mapDispatchToProps ليس إلزاميًا تمامًا ، لم أقم بتضمينه في مثالنا. إذا لم تقم بتمرير mapDispatchToProps وتمرير القيمة null بدلاً من ذلك ، فلا يزال بإمكانك الوصول إلى وظيفة الإرسال في المكون الخاص بك كما فعلنا سابقًا this.props.dispatch.

حتى ننتهي من تطبيق المثال الخاص بنا ، كل ما يتعين علينا القيام به هو تصدير المكون الخاص بنا مع تغليفه بوظيفة الاتصال والمرور في mapStateToProps الذي حددناه للتو.

وهذا كل شيء! هذا تنفيذ كامل لمتجر Redux. انظر أدناه للحصول على مثال عملي لما نفذناه.

مثال كامل للكود المشروح

App.js Todo.js

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