MobX أو Redux: أيهما أفضل لإدارة حالة رد الفعل؟



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

دعونا أولاً نلقي نظرة على الأشياء المشتركة بين الاثنين:

1) كلاهما دعم تصحيح وقت السفر
2) كلاهما يحتوي على مكتبات مفتوحة المصدر
3) كلاهما يوفر إدارة حالة من جانب العميل
4) كلاهما يوفر دعماً هائلاً لأطر React الأصلية

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

-> الصيانة وقابلة للتطوير

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

-> عملية التصحيح

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

-> منحنى التعلم

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

-> المجتمع

لدى Redux قاعدة مجتمعية كبيرة بالمقارنة مع MobX. وبالتالي ، توفر Redux دعمًا اجتماعيًا كبيرًا للمطورين في أي وقت وفي أي مكان.

-> نجس مقابل نقية

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

-> يمكن ملاحظتها مقابل البيانات العادية

يستخدم MobX ملفًا يمكن ملاحظته للتخزين بينما يستخدم Redux بيانات Javascript العادية لتخزين القيم. في Redux ، يتم تعقب جميع التحديثات يدويًا.

-> المتجر

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

الإعادة مقابل MobX: مقارنة الكود

حقن الدعائم

تستخدم وظيفة connect () React-redux لتمرير الحالة والإجراءات إلى الدعائم في Redux. هو مبين أدناه:

// الوصول إلى الدعائم

<ContactForm contact={this.props.contact} loading={this.props.loading} onSubmit={this.submit} /> 


// وظيفة لحقن الدولة في الدعائم

 function mapStateToProps(state) { return { contact: state.contactStore.contact, errors: state.contactStore.errors } } 


// حقن كل من الدولة والإجراءات في الدعائم

 export default connect(mapStateToProps, { newContact, saveContact, fetchContact, updateContact })(ContactFormPage); 


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

 @inject("stores") @observer // injecting store into props class ContactFormPage extends Component { … // accessing store via props const { contactStore:store } = this.props.stores; return ( <ContactForm store={store} form={this.form} contact={store.entity} /> ) … } 


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

إلباس الحذاء

في Redux ، أولاً ، حدد المتجر ويتم تمرير التطبيق عبر موفر. للتعامل مع الوظائف غير المتزامنة ، تحتاج أيضًا إلى تحديد الوسيطة redux-thunk و redux-وعد. بعد ذلك ، تسمح ميزة redux-devtools-extension بتخزين الأخطاء في وضع السفر عبر الزمن.

 import { applyMiddleware, createStore } from "redux"; import thunk from "redux-thunk"; import promise from "redux-promise-middleware"; import { composeWithDevTools } from 'redux-devtools-extension'; import rootReducer from "./reducers"; const middleware = composeWithDevTools(applyMiddleware(promise(), thunk)); export default createStore(rootReducer, middleware); 


// src / index.js

 ReactDOM.render( <BrowserRouter> <Provider store={store}> <App /> </Provider> </BrowserRouter>, document.getElementById('root') ); 


في MobX ، يتم إعداد متاجر متعددة. لا يحتاج إلى مكتبات خارجية للتعامل مع إجراءات المزامنة ولكن فقط بضعة أسطر من التعليمات البرمجية. أنت بحاجة إلى mobx-remotedev لتوصيل أداة تصحيح أخطاء redux-devtools-extension.



 import remotedev from 'mobx-remotedev'; import Store from './store'; const contactConfig = { name:'Contact Store', global: true, onlyActions:true, filters: { whitelist: /fetch|update|create|Event|entity|entities|handleErrors/ } }; const contactStore = new Store('api/contacts'); const allStores = { contactStore: remotedev(contactStore, contactConfig) }; export default allStores; 


// src / index.js

 ReactDOM.render( <BrowserRouter> <Provider stores={allStores}> <App /> </Provider> </BrowserRouter>, document.getElementById('root') ); 


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

تحديد الإجراءات و المخفضات

يتم تعريف الإجراءات ومخفضات في Redux بواسطة التعليمات البرمجية التالية:

// الإجراءات

 export function fetchContacts(){ return dispatch => { dispatch({ type: 'FETCH_CONTACTS', payload: client.get(url) }) } } 


// مخفضات

 switch (action.type) { case 'FETCH_CONTACTS_FULFILLED': { return { ...state, contacts: action.payload.data.data || action.payload.data, loading: false, errors: {} } } case 'FETCH_CONTACTS_PENDING': { return { ...state, loading: true, errors: {} } } case 'FETCH_CONTACTS_REJECTED': { return { ...state, loading: false, errors: { global: action.payload.message } } } } 


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

 @action fetchAll = async() => { this.loading = true; this.errors = {}; try { const response = await this.service.find({}) runInAction('entities fetched', () => { this.entities = response.data; this.loading = false; }); } catch(err) { this.handleErrors(err); } } 


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

لماذا تستخدم تطبيقات MobX for React؟

MobX هي مكتبة تم اختبارها تجعل إدارة الحالة بسيطة وقابلة للتطبيق من خلال تطبيق البرمجة التفاعلية التفاعلية (TFRP) بشفافية. React و MobX هي مزيج قوي معًا.

  • أقل رمز للكتابة
  • سهل التعلم
  • البيانات المتداخلة سهلة
  • دعم البرمجة وجوه المنحى


لماذا لا تستخدم MobX؟

  • يصعب تصحيحه
  • بدائل أفضل موجودة
  • يعطي الكثير من الحرية


لماذا تستخدم تطبيقات Redux for React؟

Redux هي مكتبة قائمة بذاتها يمكن استخدامها مع إطار واجهة المستخدم بما في ذلك Angular و Vue و Ember و React & vanilla JS.

  • القابلية للتوسعة عبر البرامج الوسيطة
  • الشعبية والمجتمع
  • دعم الأدوات
  • القدرة على التنبؤ والبساطة
  • تدفق البيانات أحادي الاتجاه وثباته
  • فصل البيانات والعرض


لماذا لا تستخدم Redux؟

  • Boilerplate (المخفضات ، المحددات ، المشاهدات ، أنواع الإجراءات ، منشئو الإجراءات ، ...)
  • يتم فصل الإجراءات عن تأثيرها (كما هو محدد في المخفض)
  • لا يوجد حل جاهز للتعامل مع الآثار الجانبية (متاح عبر البرامج الوسيطة مثل redux-thunk أو redux-saga)


ملاحظة أخيرة:

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

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

آمل أن أكون قد قدمت معلومات كافية لتوضيح ما إذا كنت تريد الترحيل إلى MobX أو المتابعة مع Redux. في النهاية ، يعتمد القرار على نوع المشروع الذي تعمل عليه والموارد المتاحة لك.

Source: https://habr.com/ru/post/ar480692/


All Articles