استخدام Mobx كمدير دولة في React Native Applications
نشرت: 2022-03-10تعد إدارة الدولة جزءًا لا يتجزأ من تطوير تطبيقات 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 نفسه عن غيره من مديري الدولة بالمفاهيم التالية.
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
لإرجاع القوائم ، والتي نستخدمها بعد ذلك في بناء القائمة الفردية عن طريق تمرير العنصر المرتجع كعوامل خاصة إلى مكون القائمة .
بمجرد الانتهاء من ذلك ، يجب أن يبدو المكون الخاص بنا على هذا النحو مع إضافة القوائم:
التالي هو إضافة مكونات 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