كيفية دمج Redux في تطبيقك مع React Native و Expo

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

الحاجة لإحياء

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

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

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

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

الدولة هناك لتغيير البيانات. هذا هو السبب الوحيد لوجود الدولة داخل كل مكون. عندما نريد تغيير الحالة ، نستخدم this.setState()طريقة داخل مكون. تعيد هذه الطريقة تصيير المكون وكافة مكوناته الفرعية لتعكس التغييرات. يعمل هذا في كل من React و React Native بشكل مشابه ، لكن العناصر الداخلية مختلفة.

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

تعد Redux واحدة من أكثر الطرق المعتمدة على نطاق واسع لمعالجة البيانات. إنه يمكّن الدولة من المشاركة كسمة عامة يمكن لتطبيق React Native بأكمله استخدامها واستلامها في شكل دعائم. يُعرف هذا بإنشاء متجر في Redux. يبسط Redux الحالة بنقلها إلى مكان واحد.

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

فقط تذكر المصطلحات التالية ، لأننا سنراها أثناء العمل في البرنامج التعليمي أدناه:

  • أجراءات
  • مخفضات
  • متجر

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

بناء تطبيق بومودورو

البدء مع Expo-CLI؟

لإنشاء هذا التطبيق ، سأستخدم أحدث أداة قدمها فريق Expo تسمى expo-cli. قم بتثبيته على أنه تبعية عالمية ثم ابدأ مشروع React Native جديدًا باستخدامه.

لمعرفة ما إذا كان كل شيء يعمل بشكل صحيح في هذه الحالة الأولية ، قم بتشغيل الأمر التالي.

ستتم مطالبتك بالواجهة التالية. خذ بعض الوقت لتتصفحها. إذا كنت قد قمت بإنشاء تطبيقات باستخدام Expo XDE أو Create-React-Native-App من قبل ، فسترى أنه لم يتغير الكثير ، باستثناء أن Expo-CLI الآن يستخدم متصفح Chrome.

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

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

مكون المؤقت ⏱

أولاً ، سننشئ مكون Timer غبي ونوصله بـ App.js. أضف الكود التالي إلى Timer/index.js:

بعد ذلك ، قم بتعديل App.jsالملف:

سنقوم الآن بإنشاء مكون مؤقت ثابت لنرى كيف تتلاءم الأشياء. سنبدأ بتعديل StatusBar. ثم نحدد Textعنصرين من react-nativeالمكتبة لتحديد مكان عرض المؤقت الفعلي ومكان عرض الأزرار لبدء وإيقاف المؤقت. في الوقت الحالي ، كلاهما عبارة عن حقول نصية.

إضافة الأزرار؟

في هذا القسم ، سنقوم باستبدال القسم الذي يتم عرضه Start and Stop Buttons!بأزرار فعلية. سوف نستخدم TouchableOpactiyلجعل هذا العمل. و TouchableOpacityيعمل عنصر بمثابة مجمع لجعل جهات النظر الاستجابة بشكل مناسب لمسات. يتم تقليل عتامة العرض المغلف (أو الزر الموجود في حالتنا) عندما يلمسها المستخدم.

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

هذا مكون عديم الحالة ، لذلك لا يحتوي على فئة - نحن بحاجة إليه فقط لتمثيل الزر في واجهة المستخدم لتطبيقنا. نقوم أيضًا باستيراد أيقونات FontAwesome من @expo/vector-icons، وهي مجموعة من رموز المتجهات التفاعلية الأصلية وتأتي مباشرةً مع expo SDK. لا حاجة لتثبيته كتبعية منفصلة. لعرض رمز ، نحتاج إلى تحديد size.

أخيرًا ، في المكون عديم الجنسية أعلاه ، نحدد propTypes. سأناقش كيف ولماذا يجب أن نستخدم PropTypes في تطبيق React Native في مقال آخر.

في تطبيق الهاتف ، يتم تشغيل الأحداث عن طريق اللمس. للتعامل مع تلك الأحداث ، سوف نستخدم onPress. سيكون لدينا حدثان فقط هنا ، Start and Stop. سيستفيد كل من الأزرار الموجودة في تطبيقنا من onPressOutأيهما يختلف عن onPress. و onPressOutيسمى كلما يتم تحريرها لمسة من قبل المستخدم (عندما يتوقف المستخدم الضغط على زر). يتم استدعاؤه من قبل onPressوهو أكثر دقة في موقف مثل حالتنا حيث نحتاج إلى بدء أو إيقاف المؤقت عن طريق الضغط على الزر بمجرد انتهاء المستخدم.

سنطلب الآن هذا Buttonالمكون في مكون المؤقت الخاص بنا.

دمج الإحياء؟

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

الآن ، دعونا نبدأ في دمج Redux في تطبيقنا.

أجراءات ؟

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

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

طلبنا يحتاج فقط إلى ثلاثة إجراءات حتى الآن. نوع أي إجراء هو قيمة سلسلة ويتم تعريفه على أنه ثابت.

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

مخفضات؟

يُعرف جهاز استقبال الإجراء باسم المخفض. عندما يتم تشغيل إجراء ما ، تتغير حالة التطبيق. تتم معالجة حالة التطبيق بواسطة المخفضات.

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

في حالتنا الأولية ، نحدد ثلاث سمات: isPlaying، elapsedTimeو timerDuration. يحتوي المؤقت حاليًا على قيمة افتراضية تبلغ 6 (ثوانٍ) لأغراض الاختبار ، لكن القيمة الفعلية التي سنغيرها لاحقًا هي 25(أو 1500 ثانية).

ثم هناك ثلاث وظائف مساعدة:

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

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

هذا مصدر جيد للبدء في Redux بشكل عام بواسطة Dan Abramov وهو مجاني!

إنشاء متجر Redux؟

بمساعدة المخفض والحالة الأولية ، يمكننا إنشاء كائن store.

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

لربط تطبيق React أو React Native مع Redux ، يمكنك القيام بذلك باستخدام react-reduxالوحدة النمطية. يتم ذلك باستخدام مكون عالي الترتيب Provider. إنه يمرر المتجر بشكل أساسي إلى بقية التطبيق.

نحتاج إلى ربط صانعي الإجراءات بوظيفة Timer الخاصة بنا لجعلها تعمل بكامل طاقتها (بحيث تستجيب للأحداث التي يمكن لمسها أو بدء المؤقت أو إعادة تشغيله). سنفعل هذا في Timer/index.jsالوظيفة.

أولاً ، نقوم باستيراد التبعيات المطلوبة لربط منشئي الإجراءات.

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

نحدد هاتين الوظيفتين ونعدل بياننا export defaultبعد أن نحدد أنماط وجهات نظرنا الأصلية المتفاعلة.

mapStateToPropsهو كائن يعيش في المتجر يتم تمرير مفاتيحه إلى المكون كدعامات. فيما يلي رمز كامل لمكون المؤقت.

إكمال التطبيق ⚛️ +؟

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

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

لقد وصلنا إلى نهاية المقال. آمل أن تكون قد استمتعت بقراءته بقدر ما استمتعت بكتابته. يمكنك العثور على الكود الكامل لهذه المقالة في Github repo:

amandeepmittal / rn-pomodoro-example

آر-بومودورو-مثلا - يردون الأصلية + مسترجع integaration github.com

هل تتذكر أنني أخبرك عن بنية ملف معينة اتبعتها في تنفيذ بنية Redux؟ حسنًا ، يُطلق عليه نمط إعادة البط ويمكنك العثور على مزيد من التفاصيل في هذه المقالة المفيدة بواسطة Alex Moldovan:

توسيع نطاق تطبيق Redux الخاص بك مع البط

كيف مقياس تطبيق الواجهة الأمامية؟ كيف تتأكد من أن الشفرة التي تكتبها قابلة للصيانة لمدة 6 أشهر ... medium.freecodecamp.org

؟ لمزيد من الأسئلة ، اتصل بي على Twitter ، أو اقرأ المزيد عني على موقع الويب الخاص بي.

إذا كنت ترغب في تلقي تحديثات حول مقالتي التالية حول React Native ، فيرجى التفكير في الاشتراك في رسالتي الإخبارية.