تعرف على كيفية استخدام Redux

Redux هو مدير دولة يستخدم عادةً مع React ، لكنه غير مرتبط بتلك المكتبة. تعلم Redux من خلال قراءة هذا الدليل البسيط والسهل المتابعة

لماذا تحتاج Redux

Redux هو مدير دولة يستخدم عادةً مع React ، لكنه غير مرتبط بهذه المكتبة - يمكن استخدامه مع تقنيات أخرى أيضًا ، لكننا سنلتزم بـ React من أجل الشرح.

لدى React طريقتها الخاصة في إدارة الحالة ، كما يمكنك أن تقرأ في ملفدليل React للمبتدئين، حيث أقدم كيف يمكنك إدارة State في React.

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

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

يعد Redux طريقة لإدارة حالة التطبيق ، ونقله إلى ملفمتجر عالمي خارجي.

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

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

متى يجب استخدام Redux؟

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

لا يجب أن تحتاج التطبيقات البسيطة إليه على الإطلاق (ولا حرج في التطبيقات البسيطة).

شجرة الدولة الثابتة

في Redux ، يتم تمثيل الحالة الكاملة للتطبيق بواسطةواحد JavaScriptكائن يسمىحالةأوشجرة الدولة.

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

لا يمكن تغييره إلا عن طريق إرسال ملففعل.

أجراءات

انفعليكونكائن JavaScript يصف تغييرًا بأدنى حد(بالمعلومات المطلوبة فقط):

{
  type: 'CLICKED_SIDEBAR'
}

// e.g. with more data { type: ‘SELECTED_USER’, userId: 232 }

الشرط الوحيد لكائن العمل هو وجودtypeالخاصية ، التي تكون قيمتها عادةً سلسلة.

يجب أن تكون أنواع الإجراءات ثوابت

في تطبيق بسيط ، يمكن تعريف نوع الإجراء كسلسلة.

عندما ينمو التطبيق ، من الأفضل استخدام الثوابت:

const ADD_ITEM = 'ADD_ITEM'
const action = { type: ADD_ITEM, title: 'Third item' }

وفصل الإجراءات في ملفاتهم الخاصة ، واستيرادها

import { ADD_ITEM, REMOVE_ITEM } from './actions'

المبدعين العمل

منشئو الإجراءاتهي الوظائف التي تخلق الإجراءات.

function addItem(t) {
  return {
    type: ADD_ITEM,
    title: t
  }
}

عادةً ما تقوم بتشغيل منشئ الإجراءات جنبًا إلى جنب مع تشغيل المرسل:

dispatch(addItem('Milk'))

أو عن طريق تحديد وظيفة مرسل الإجراء:

const dispatchAddItem = i => dispatch(addItem(i))
dispatchAddItem('Milk')

مخفضات

عند إطلاق إجراء ما ، يجب أن يحدث شيء ما ، ويجب أن تتغير حالة التطبيق.

هذه هي وظيفةمخفضات.

ما هو المخفض

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

;(currentState, action) => newState

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

ما لا ينبغي أن يفعله المخفض

يجب أن يكون المخفض وظيفة نقية ، لذلك يجب أن:

  • لا تغير حججها
  • لا تغير الحالة أبدًا ، ولكن بدلاً من ذلك أنشئ دولة جديدة بهاObject.assign({}, ...)
  • لا تولد أبدًا آثارًا جانبية (لا توجد استدعاءات API تغير أي شيء)
  • لا تستدعي أبدًا وظائف غير نقية ، وظائف تغير مخرجاتها بناءً على عوامل أخرى غير مدخلاتها (على سبيل المثالDate.now()أوMath.random())

لا يوجد تعزيز ، لكن يجب عليك الالتزام بالقواعد.

مخفضات متعددة

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

محاكاة المخفض

يمكن تبسيط Redux في جوهره باستخدام هذا النموذج البسيط:

الولاية

{
  list: [
    { title: "First item" },
    { title: "Second item" },
  ],
  title: 'Groceries list'
}

قائمة الإجراءات

{ type: 'ADD_ITEM', title: 'Third item' }
{ type: 'REMOVE_ITEM', index: 1 }
{ type: 'CHANGE_LIST_TITLE', title: 'Road trip list' }

مخفض لكل جزء من الدولة

const title = (state = '', action) => {
    if (action.type === 'CHANGE_LIST_TITLE') {
      return action.title
    } else {
      return state
    }
}

const list = (state = [], action) => { switch (action.type) { case ‘ADD_ITEM’: return state.concat([{ title: action.title }]) case ‘REMOVE_ITEM’: return state.filter(item => action.index !== item.index) default: return state } }

مخفض للدولة بأكملها

const listManager = (state = {}, action) => {
  return {
    title: title(state.title, action),
    list: list(state.list, action)
  }
}

المتجر

المحلهو كائن:

  • يحمل الدولةمن التطبيق
  • يفضح الدولةعبرgetState()
  • يسمح لناتحديث الدولةعبرdispatch()
  • يسمح لنا (إلغاء) تسجيل أمستمع تغيير الدولةاستخدامsubscribe()

المتجرفريدة من نوعهافي التطبيق.

إليك كيفية إنشاء متجر لتطبيق listManager:

import { createStore } from 'redux'
import listManager from './reducers'
let store = createStore(listManager)

هل يمكنني تهيئة المتجر ببيانات من جانب الخادم؟

بالتأكيد،فقط قم بتمرير حالة البداية:

let store = createStore(listManager, preexistingState)

الحصول على الدولة

store.getState()

تحديث الدولة

store.dispatch(addItem('Something'))

استمع إلى تغييرات الحالة

const unsubscribe = store.subscribe(() =>
  const newState = store.getState()
)

unsubscribe()

تدفق البيانات

تدفق البيانات في Redux دائمًاأحادي الاتجاه.

أنت أتصلdispatch()في المتجر ، تمرير إجراء.

يعتني المتجر بتمرير الإجراء إلى Reducer ، مما يؤدي إلى إنشاء الحالة التالية.

يقوم المتجر بتحديث الحالة وينبه جميع المستمعين.

تحميل مجانيكتيب رد الفعل


المزيد من البرامج التعليمية للتفاعل: