استخدام Mobx كمدير دولة في React Native Applications

نشرت: 2022-03-10
ملخص سريع ↬ MobX هي واحدة من العديد من أدوات إدارة الحالة المتاحة لمطوري React. في هذا البرنامج التعليمي ، يشرح Fortune Kay ماهية MobX وكيف يمكنك استخدامه في تطبيقات React من خلال إنشاء واحد من البداية.

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

ملاحظة: ستكون المعرفة الأساسية بجافا سكريبت و React Native ذات فائدة كبيرة أثناء عملك من خلال هذا البرنامج التعليمي.

استخدام تطبيقات MobX In React

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

ومع ذلك ، من المهم معرفة أن الحالة ليست هي البيانات الوحيدة التي يعرضها المكون ، بل يمكن للمكونات أيضًا أن تعرض الدعائم التي تم تمريرها إليها.

خيارات لإدارة الدولة

مكتبات إدارة الدولة لتطبيقات React Native تتضمن ؛ React Context API و Redux و MobX و Unstated Next.

على الرغم من أن كل من مديري الدولة لديهم مزايا وعيوب ، فإنني شخصياً أوصي باستخدام MobX بسبب بساطته ، والحد الأدنى من الكود المعياري - فهو لا يتطلب منك تغيير الكود الخاص بك ، وهذا لأنه في جوهره ، MobX هو ويبدو مثل JavaScript ؛ لا تحتاج إلى تغيير في البنية لدعمها (على عكس Redux وبدرجة أقل السياق).

في الحقيقة إنه تجريد غير مرئي أنه في كثير من الحالات إذا قمت بإزالة كل كود MobX -observable وcomputed و action و Observer decorators ، فإن الكود الخاص بك سيعمل تمامًا (على الرغم من أنه سيواجه بعض مشكلات الأداء ) ولا يقتصر على دولة عالمية. هذه بعض الأسباب للمضي قدمًا مع MobX كمدير حكومي مفضل لتطبيقات React Native الخاصة بك.

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

ما هو MobX؟

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

هندسة حالة MobX
هندسة حالة MobX. (معاينة كبيرة)
المزيد بعد القفز! أكمل القراءة أدناه ↓

المبادئ الأساسية ومفهوم MobX

تميز MobX نفسه عن غيره من مديري الدولة بالمفاهيم التالية.

1. الدولة

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

2. المشتقات

في MobX ، أي شيء يمكن اشتقاقه من الحالة بدون تفاعلات هو اشتقاق. من أمثلة الاشتقاقات ما يلي:

  • واجهة المستخدم،
  • الوظائف الإضافية للواجهة الخلفية مثل التغييرات على الخادم.

يحتوي MobX على نوعين رئيسيين من المشتقات:

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

القاعدة الذهبية عند استخدام MobX هي أنه عند إنشاء قيمة بناءً على الحالة الحالية ، استخدم قيمة محسوبة.

3. الإجراءات

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

لفهم الإجراءات بشكل أفضل ، دعنا نلقي نظرة على مثال من وثائق MobX.

 class Ticker { @observable tick = 0 @action increment() { this.tick++ // 'this' will always be correct } } const ticker = new Ticker() setInterval(ticker.increment, 1000)

هنا ، قمنا بتعيين علامة @observable بقيمة أولية قدرها 0. بعد ذلك ، أنشأنا زيادة دالة والتي تعد أيضًا إجراءً يُحدِّث القيمة الأولية بمجرد إجراء علامة كل ثانية.

المراقبات في MobX

القيم التي يمكن ملاحظتها أو القيم التي يمكن ملاحظتها في MobX هي في الغالب بدائل JavaScript وكائنات عادية وفئات ومصفوفات وخرائط. يتم استخدامها في الغالب من خلال الإعلان أولاً عن ما يمكن ملاحظته وإضافة قيمة إليه ثم استدعاؤه عن طريق إضافةobservable كما هو موضح أدناه:

 observable(value) @observable classProperty = value

نهج معمارية المتجر في MobX

تشتمل بنية MobX الرئيسية على أجزاء وأفكار مثل الخدمات والتخزين وعرض النماذج والحاويات - بعضها موضح أدناه.

  • خدمة
    عادة ما تكون هذه وظيفة تسمى من الحاوية ؛ يمكن استخدامها للحصول على البيانات من واجهات برمجة التطبيقات وإضافتها إلى المتجر.
  • متجر
    كما يوحي الاسم ، هذا هو المكان المركزي للدولة التي يستخدمها التطبيق. عادةً في MobX ، تتضمن هذه العناصر الملحوظة والمتغيرات والإجراءات والخصائص المحسوبة.
  • حاوية
    تستدعي هذه service وتضع البيانات من View Model to View Component باعتبارها React props (يجب تمييزها بـ @observer decorator).

MobX في التفاعل والتطبيقات الأصلية

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

بدون مزيد من اللغط ، لنبدأ!

تهيئة بيئتك

الآن بعد أن عرفنا ماهية MobX وكيف يعمل ، دعني أطلعك على إعداد مشروعك.

أولاً ، دعنا ننشئ مشروعًا بما يلي ، اكتب الكود التالي على جهازك الطرفي لتهيئة المشروع:

 npx create-react-app listapp

ستنشئ الشفرة أعلاه تطبيق React عارية باستخدام حزمة create-reaction-app. انتقل إلى دليل المشروع:

 cd listapp

بالنسبة لهذا التطبيق ، سنحتاج إلى ثلاثة مكونات:

  • TitleInput
    سيحتوي هذا على عنوان مشروعنا ونموذج إدخال لإضافة القوائم.
  • List
    سيكون هذا نموذج إدخال من شأنه أن يسمح للمستخدم بإضافة قائمة. سيكون به زر إضافة لإضافة عناصر قائمتنا.
  • ListsDisplay
    سيعرض هذا المكون جميع عناصر قائمة المستخدمين وأيضًا زر حذف يتم إنشاؤه تلقائيًا عندما يضيف المستخدم عنصر قائمة.

سنستخدم Store.js لاحتواء حالة التطبيق وطرق تعديله على غرار Redux. دعنا نحدد ما سيتم استخدامها من أجله.

  • mobx
    هذا هو مدير الدولة الذي سنستخدمه لهذا المشروع.
  • mobx-react
    هذه هي ارتباطات React الرسمية لـ MobX.
  • bootstrap
    سنستخدم الإصدار 4.5 من bootstrap لتصميم مشروعنا.
  • uuid
    يستخدم هذا لإنشاء مفاتيح تلقائيًا لحذف القوائم.

بعد القيام بذلك ، دعنا نمضي قدمًا ونثبت هذه الحزم. سأقوم بتثبيتها باستخدام بديل npm يتم إجراؤه في الغزل:

 yarn add mobx mobx-react [email protected] uuid

بمجرد تثبيت الحزم ، سنبدأ تطبيقنا في وضع التطوير عن طريق تشغيل الكود أدناه في جهازك:

 yarn start

إنشاء متجر التطبيقات الخاص بنا

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

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

 /*** src/Store.js ***/ import { observable, action, computed } from "mobx"; import { v4 } from "uuid"; export class List { @observable value @observable done constructor (value) { this.id = v4() this.value = value } } export class ListStore { @observable lists = [] @observable filter = "" @action addList = (value) => { this.lists.push(new List(value)) } @action deleteList = (list) => { this.lists = this.lists.filter(t => t !== list) } @computed get filteredLists () { const matchCase = new RegExp(this.filter, "i") return this.lists.filter(list=> !this.filter || matchCase.test(list.value)) } }

في الكود أعلاه ، قمنا باستيراد ثلاث وظائف من mobx .

  • observable
    يحمل هذا متغيرًا يمكن تحديثه في حالة حدوث تغيير في الحالة.
  • action
    يستخدم لتعديل حالة التطبيق.
  • computed
    القيم التي يمكن اشتقاقها من الحالة الحالية أو القيم المحسوبة الأخرى ، تتغير بعد تعديل الحالة.

تحتوي List الفئات على قيمتين للكائن done value التي ستحتفظ بالحالة الأولية للتطبيق والتعديل في حالة التغييرات.

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

بعد ذلك ، أضفنا وظيفة addList التي ستضيف قوائم عند النقر عليها باستخدام طريقة .push() لدفع القائمة في المصفوفة التي أنشأناها بالفعل في مصفوفة @observable lists .

تقبل وظيفة deleteList List باعتبارها خاصية من المفترض أن تكون العنصر الذي يريد المستخدم إزالته. ثم نقوم بتعيين قيمة هذه this.Lists في مصفوفة جديدة بعد إزالة العنصر المحدد.

تعد كل من addLists و deleteList إجراءات لأنها تعدل حالة تطبيقنا عند إجراء التغييرات.

جارٍ بدء متجر MobX

التالي في قائمتنا هو استيراد متجرنا في App.js واستخدامه في مشروعنا.

 import React from 'react'; import Navbar from "./components/navbar"; import ListDisplay from "./components/ListDisplay"; import {ListStore} from './ListStore'; function App() { const store = new ListStore() return ( <div> <Navbar store={store}/> <ListDisplay store={store}/> </div> ); } export default App;

هنا قمنا باستيراد مكونات TitleInput و ListDisplay . ثم قمنا بتهيئة المتجر في App.js لدينا حتى نتمكن من تمريره كدعامات إلى مكونات TitleInput و ListDisplay .

عادةً ما يؤدي هذا إلى حدوث خطأ لأننا لم نعمل على المكونات الأخرى ، لذلك دعونا نفعل ذلك. دعونا نبني مكون ListDisplay .

ListDisplay

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

 import React from 'react' import List from "./List"; import { observer } from 'mobx-react'; function ListDisplay(props) { const { deleteList, filteredLists } = props.store return ( <div> <div className="container"> {filteredLists.map(list => ( <List key={list.id} list={list} deleteList={deleteList} /> ))} </div> </div> ) } export default observer(ListDisplay)

بالنسبة لهذا المكون ، أنشأنا وظيفة ListDisplay مراقبًا ، كما قمنا أيضًا بتدمير list deletelist وظائف القائمة من المتجر ، من خلال القيام بذلك ، جعلنا الأمر أسهل لتمريرها كدعائم كائن.

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

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

مكون عرض القائمة
القوائم المعروضة بواسطة مكون `ListDisplay`. (معاينة كبيرة)

التالي هو إضافة مكونات List و TitleInput .

مكون القائمة

تمامًا مثل مكوناتنا الأخرى ، سيقوم مكون List لدينا بتصدير القائمة كمراقب لمساعدة المتجر على مراقبتها من أجل التغييرات.

 import React from 'react' import { observer } from 'mobx-react' function List(props) { return ( <div className="card"> <div className="card-body"> <div className="d-flex justify-content-between align-items-center"> <p className={`title ${props.list.done ? "text-secondary" : ""}`}> {props.list.value} </p> <div> <button onClick={props.deleteList.bind(this, props.list)} className="btn btn-danger font-weight-bold py-2 px-5 ml-2"> Delete </button> </div> </div> </div> </div> ) } export default observer(List)

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

مكون القائمة
مكون قائمة واحد مع زر الحذف. (معاينة كبيرة)

التالي هو TitleInput الخاص بنا والذي سيحتوي على نموذج الإدخال الخاص بنا لإضافة القوائم وعنوان المشروع.

TitleInput

على غرار مشاريعنا الأخرى ، سنضيف وظيفة @observer حتى يتمكن المكون من قبول الدعائم من متجر التطبيقات.

 import React, { useState } from 'react' import { observer } from 'mobx-react' function Navbar(props) { const [value, setValue] = useState("") const {addList} = props.store const prepareAddList = (e) => { e.preventDefault() addList(value) setValue("") } return ( <div className="container mt-3"> <h1 className="title">List App</h1> <form onSubmit={prepareAddList} className="form-group"> <div className="row ml-lg-2"> <input className="form-control-lg col-12 col-lg-9 col-sm-12 mr-3 border border-secondary" value={value} type="text" onChange={(e) => setValue(e.target.value)} placeholder="Enter list" /> <button className="col-lg-2 col-5 col-sm-5 mt-2 mt-lg-0 mt-sm-2 btn btn-lg btn-success font-weight-bold"> Add to List </button> </div> </form> </div> ) } export default observer(Navbar)

أولاً ، قمنا بتهيئة حالة أولية. باستخدام React Hooks ، أضفنا حالة أولية تسمى values التي قمنا بتعيينها على سلسلة فارغة. نستخدم هذا للاحتفاظ بقيمة ما تم إدخاله في حقل الإدخال. لمعرفة المزيد عن React Hooks ، يمكنك الاطلاع على هذا المقال بقلم David Abiodun.

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

بعد ذلك أنشأنا دالة preparedAddList لقبول كائن حدث لنماذج الإدخال ، أضفنا أيضًا زرًا لإضافة القوائم يدويًا عند النقر.

أوشكنا على الانتهاء ، نحتاج إلى إعادة تشغيل خادم المشروع عن طريق تشغيل:

 yarn start

ويجب أن يبدو TitleInput بنا كما يلي:

إدخال عنوان
مكون العنوان والمدخلات. (معاينة كبيرة)

لقد انتهينا الآن من جميع مكونات التطبيق ، لذا فلنجمعها في App.js للقيام بذلك ، نحتاج إلى استيراد titleInput و ListDisplay . نحتاج أيضًا إلى استيراد متجرنا من مكون المتجر.

لكي يعمل MobX في تطبيقنا ، نحتاج إلى تمرير متجر MobX كدعامات في تطبيقنا ومكونات فردية حتى يحصلوا على الخصائص والوظائف في المتجر.

 import React from 'react'; import Navbar from "./components/navbar"; import ListDisplay from "./components/ListDisplay"; import {ListStore} from './ListStore'; function App() { const store = new ListStore() return ( <div> <Navbar store={store}/> <ListDisplay store={store}/> </div> ); } export default App;

يجب أن يبدو تطبيقنا هكذا عند اكتماله:

تطبيق قائمة مكتمل
(معاينة كبيرة)

خاتمة

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

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

المراجع والمصادر

  • "تفاعل مع MobX - بدء الاستخدام" ، نادر ضبيط ، متوسط
  • "المفاهيم والمبادئ" MobX (الوثائق الرسمية)
  • "أفضل الممارسات مع خطافات التفاعل" ، Adeneye David Abiodun ، مجلة Smashing