Redux Saga هي مكتبة تستخدم للتعامل مع الآثار الجانبية في Redux. عندما تطلق إجراءً ما ، يتغير شيء ما في حالة التطبيق وقد تحتاج إلى القيام بشيء ناجم عن هذا التغيير في الحالة
- متى تستخدم Redux Saga
- مثال أساسي على استخدام Redux Saga
- كيف تعمل وراء الكواليس
- المساعدين الأساسيين
- تشغيل التأثيرات بالتوازي
متى تستخدم Redux Saga
في تطبيق يستخدمإعادة، عندما تطلق إجراءً يتغير شيء ما في حالة التطبيق.
عندما يحدث هذا ، قد تحتاج إلى القيام بشيء مشتق من هذا التغيير في الحالة.
على سبيل المثال قد ترغب في:
- قم بإجراء مكالمة HTTP إلى الخادم
- إرسال حدث WebSocket
- إحضار بعض البيانات من ملفGraphQLالخادم
- حفظ شيء ما في ذاكرة التخزين المؤقت أو التخزين المحلي للمتصفح
... لقد خطرت لك الفكرة.
هذه كلها أشياء لا تتعلق حقًا بحالة التطبيق ، أو غير متزامنة ، وتحتاج إلى نقلها إلى مكان مختلف عن أفعالك أو مخفضاتك (بينما أنت تقنيًايستطع، إنها ليست طريقة جيدة للحصول على قاعدة بيانات نظيفة).
أدخل Redux Saga ، وهو برنامج وسيط من Redux يساعدك في مواجهة الآثار الجانبية.
مثال أساسي على استخدام Redux Saga
لتجنب الغوص في الكثير من النظريات قبل عرض بعض التعليمات البرمجية الفعلية ، أقدم بإيجاز كيف حللت مشكلة واجهتها عند إنشاء تطبيق نموذجي.
في غرفة الدردشة ، عندما يكتب مستخدم رسالة ، أعرض الرسالة فورًا على الشاشة ، لتقديم ملاحظات سريعة. يتم ذلك من خلال أإعادة العمل:
const addMessage = (message, author) => ({
type: 'ADD_MESSAGE',
message,
author
})
وتتغير الحالة من خلال مخفض:
const messages = (state = [], action) => {
switch (action.type) {
case 'ADD_MESSAGE':
return state.concat([{
message: action.message,
author: action.author
}])
default:
return state
}
}
تقوم بتهيئة Redux Saga عن طريق استيرادها أولاً ، ثم تطبيق ملفقصة طويلةكبرنامج وسيط لمتجر Redux:
//...
import createSagaMiddleware from 'redux-saga'
//...
ثم نقوم بإنشاء برمجية وسيطة ونطبقها على متجر Redux الذي تم إنشاؤه حديثًا:
const sagaMiddleware = createSagaMiddleware()
const store = createStore(
reducers,
applyMiddleware(sagaMiddleware)
)
الخطوة الأخيرة هي تشغيل الملحمة. نستورده ونمرره إلى التابع run للوسيطة
import handleNewMessage from './sagas'
//...
sagaMiddleware.run(handleNewMessage)
نحتاج فقط إلى كتابة الملحمة في./sagas/index.js
:
import { takeEvery } from 'redux-saga/effects'
const handleNewMessage = function* handleNewMessage(params) {
const socket = new WebSocket(‘ws://localhost:8989’)
yield takeEvery(‘ADD_MESSAGE’, (action) => {
socket.send(JSON.stringify(action))
})
}
export default handleNewMessage
ما يعنيه هذا الرمز هو:كل مرةالADD_MESSAGE
حرائق العمل ، نرسل رسالة إلىمآخذ الويبالخادم الذي يستجيب في هذه الحالة علىlocalhost:8989
.
لاحظ استخدامfunction*
، وهي ليست وظيفة عادية ، ولكن أمولد كهرباء.
كيف تعمل وراء الكواليس
كونهإعادةيمكن للبرمجيات الوسيطة ، Redux Saga اعتراض إجراءات Redux وإدخال وظائفها الخاصة.
هناك بعض المفاهيم التي يجب استيعابها ، وإليك الكلمات الرئيسية الرئيسية التي سترغب في تثبيتها في ذهنك ، تمامًا:قصة طويلةومولد كهرباءوالوسيطةويعدوإيقاف مؤقتوسيرة ذاتيةوتأثيروإرسالوعملواستيفاءوتم الحلوأثمروأسفرت.
أقصة طويلةهي بعض "القصة" التي تتفاعل معتأثيرالتي تسببها التعليمات البرمجية الخاصة بك. قد يحتوي ذلك على أحد الأشياء التي تحدثنا عنها من قبل ، مثل طلب HTTP أو بعض الإجراءات التي تحفظ في ذاكرة التخزين المؤقت.
نقوم بإنشاء ملفالوسيطةمع قائمةالملاحمللتشغيل ، والذي يمكن أن يكون واحدًا أو أكثر ، ونقوم بتوصيل هذه البرامج الوسيطة بمتجر Redux.
أقصة طويلةهومولد كهرباءوظيفة. عندمايعديتم تشغيل وأسفرت، الوسيطةيعلقالقصة طويلةحتى اليعديكونتم الحل.
مرة واحدة فييعديكونتم الحلالوسيطةيستأنفالملحمة ، حتى اليوم التاليأثمرتم العثور على البيان ، وهناك هومعلقمرة أخرى حتىيعد يقرر.
داخل رمز الملحمة ، ستقوم بإنشاء ملفتأثيراتباستخدام بعض الوظائف المساعدة الخاصة التي يوفرهاredux-saga
صفقة. للبدء ، يمكننا سرد:
takeEvery()
takeLatest()
take()
call()
put()
عندماتأثيريتم تنفيذقصة طويلةيكونمتوقف مؤقتاحتى التأثيريكوناستيفاء.
على سبيل المثال:
import { takeEvery } from 'redux-saga/effects'
const handleNewMessage = function* handleNewMessage(params) {
const socket = new WebSocket(‘ws://localhost:8989’)
yield takeEvery(‘ADD_MESSAGE’, (action) => {
socket.send(JSON.stringify(action))
})
}
export default handleNewMessage
عندماالوسيطةينفذhandleNewMessage
ملحمة ، ذلكتوقففي الyield takeEvery
تعليمات وينتظر(بشكل غير متزامن، بالطبع) حتىADD_MESSAGE
العملأرسل. ثم يقوم بتشغيل رد الاتصال الخاص به ، وقصة طويلةعلبةسيرة ذاتية.
المساعدين الأساسيين
المساعدون عبارة عن أفكار مجردة فوق واجهات برمجة التطبيقات الملحمية ذات المستوى المنخفض.
دعنا نقدم المساعدة الأساسية التي يمكنك استخدامها لتشغيل التأثيرات الخاصة بك:
takeEvery()
takeLatest()
take()
put()
call()
takeEvery()
takeEvery()
، المستخدم في بعض الأمثلة ، هو أحد هؤلاء المساعدين.
في الكود:
import { takeEvery } from 'redux-saga/effects'
function* watchMessages() {
yield takeEvery(‘ADD_MESSAGE’, postMessageToServer)
}
الwatchMessages
المولد يتوقف مؤقتًا حتىADD_MESSAGE
حرائق العمل ، وكل مرةحرائق ، سوف تستدعيpostMessageToServer
تعمل بشكل لا نهائي ومتزامن (ليست هناك حاجة إلىpostMessageToServer
لإنهاء تنفيذه قبل تشغيل جديد مرة واحدة)
takeLatest()
المساعد الشعبي الآخر هوtakeLatest()
، وهو مشابه جدًا لـtakeEvery()
ولكنه يسمح فقط لمعالج وظيفة واحد بالعمل في كل مرة ، مع تجنب التزامن. إذا تم إطلاق إجراء آخر أثناء استمرار تشغيل المعالج ، فسيتم إلغاؤه وتشغيله مرة أخرى بأحدث البيانات المتاحة.
كما هو الحال معtakeEvery()
لا يتوقف المولد أبدًا ويستمر في تشغيل التأثير عند حدوث الإجراء المحدد
take()
take()
مختلف من حيث أنه ينتظر مرة واحدة عند حدوث الإجراء الذي ينتظره ، يتم حل الوعد واستئناف المكرر ، حتى يتمكن من الانتقال إلى مجموعة التعليمات التالية.
put()
يرسل إجراءً إلى متجر Redux. بدلاً من المرور في متجر Redux أو إجراء الإرسال إلى الملحمة ، يمكنك فقط استخدامput()
:
yield put({ type: 'INCREMENT' })
yield put({ type: "USER_FETCH_SUCCEEDED", data: data })
التي تُرجع كائنًا عاديًا يمكنك فحصه بسهولة في اختباراتك (المزيد عن الاختبار لاحقًا).
call()
عندما تريد استدعاء بعض الوظائف في إحدى الملحمات ، يمكنك القيام بذلك باستخدام استدعاء دالة عادي يُرد بوعد:
delay(1000)
لكن هذا لا يلعب بشكل جيد مع الاختبارات. بدلا من،call()
يتيح لك التفاف استدعاء الوظيفة وإرجاع كائن يمكن فحصه بسهولة:
call(delay, 1000)
عائدات
{ CALL: {fn: delay, args: [1000]}}
تشغيل التأثيرات بالتوازي
يمكن تشغيل التأثيرات بالتوازي باستخدامall()
وrace()
، والتي تختلف كثيرًا في ما يفعلونه.
all()
إذا كنت تكتب
import { call } from 'redux-saga/effects'
const todos = yield call(fetch, ‘/api/todos’)
const user = yield call(fetch, ‘/api/user’)
الثانيfetch()
لن يتم تنفيذ المكالمة حتى تنجح المكالمة الأولى.
لتنفيذها بالتوازي ، لفهاall()
:
import { all, call } from 'redux-saga/effects'
const [todos, user] = yield all([
call(fetch, ‘/api/todos’),
call(fetch, ‘/api/user’)
])
all()
لن يتم حلها حتى كليهماcall()
إرجاع.
race()
race()
يختلف عنall()
من خلال عدم انتظار عودة جميع مكالمات المساعدين. إنه فقط ينتظر عودة أحدهم ، وقد انتهى الأمر.
إنه سباق لمعرفة من سينتهي أولاً ، ثم ننسى المشاركين الآخرين.
يتم استخدامه عادةً لإلغاء مهمة في الخلفية تعمل إلى الأبد حتى يحدث شيء ما:
import { race, call, take } from 'redux-saga/effects'
function* someBackgroundTask() {
while(1) {
//…
}
}
yield race([
bgTask: call(someBackgroundTask),
cancel: take(‘CANCEL_TASK’)
])
عندماCANCEL_TASK
يتم إصدار الإجراء ، نوقف المهمة الأخرى التي كانت ستعمل إلى الأبد.
تحميل مجانيكتيب رد الفعل
المزيد من البرامج التعليمية للتفاعل:
- مثال على تطبيق بسيط من React: جلب معلومات مستخدمي GitHub عبر واجهة برمجة التطبيقات
- أنشئ عدادًا بسيطًا باستخدام React
- إعداد VS Code لتطوير React
- كيفية تمرير الدعائم إلى مكون فرعي عبر React Router
- أنشئ تطبيقًا باستخدام Electron و React
- البرنامج التعليمي: أنشئ جدول بيانات باستخدام React
- خارطة الطريق لتعلم React
- تعرف على كيفية استخدام Redux
- الشروع في العمل مع JSX
- المكونات المصممة
- مقدمة إلى Redux Saga
- مقدمة إلى React Router
- مقدمة إلى React
- مكونات رد الفعل
- DOM الظاهري
- رد فعل الأحداث
- دولة رد الفعل
- رد فعل الدعائم
- جزء رد الفعل
- واجهة برمجة تطبيقات سياق React
- تفاعل PropTypes
- مفاهيم التفاعل: تصريحية
- React: كيفية إظهار مكون مختلف عند النقر
- كيفية التكرار داخل React JSX
- الدعائم مقابل الحالة في React
- هل يجب عليك استخدام jQuery أم React؟
- ما مقدار JavaScript الذي تحتاج إلى معرفته لاستخدام React؟
- مقدمة لغاتسبي
- كيفية الإشارة إلى عنصر DOM في React
- تدفق البيانات أحادي الاتجاه في React
- تفاعل مكونات الترتيب الأعلى
- تفاعل أحداث دورة الحياة
- مفهوم التفاعل: الثبات
- مفهوم التفاعل: النقاء
- مقدمة في React Hooks
- مقدمة حول إنشاء التطبيق التفاعلي
- مفهوم التفاعل: التركيب
- رد الفعل: العرض مقابل مكونات الحاوية
- تقسيم الكود في React
- عرض جانب الخادم باستخدام React
- كيفية تثبيت React
- CSS في React
- استخدام SASS في React
- التعامل مع النماذج في React
- رد فعل StrictMode
- تفاعل البوابات
- رد فعل الدعائم التقديم
- اختبار مكونات React
- كيفية تمرير معامل إلى معالجات الأحداث في React
- كيفية معالجة الأخطاء في React
- كيفية إرجاع عناصر متعددة في JSX
- التصيير الشرطي في React
- React ، كيفية نقل الدعائم إلى المكونات الفرعية
- كيفية الحصول على قيمة عنصر الإدخال في React
- كيفية استخدام خطاف useState React
- كيفية استخدام الخطاف useCallback React
- كيفية استخدام الخطاف useEffect React
- كيفية استخدام الخطاف useMemo React
- كيفية استخدام خطاف useRef React
- كيفية استخدام الخطاف useContext React
- كيفية استخدام خطاف useReducer React
- كيفية توصيل تطبيق React بخلفية على نفس الأصل
- البرنامج التعليمي Reach Router
- كيفية استخدام أدوات مطور React
- كيف تتعلم React
- كيفية تصحيح أخطاء تطبيق React
- كيفية عرض HTML في React
- كيفية إصلاح الخطأ "seriouslySetInnerHTML" لا يتطابق مع الخطأ في React
- كيف أصلحت مشكلة في حالة نموذج تسجيل الدخول إلى React والملء التلقائي للمتصفح
- كيفية تكوين HTTPS في تطبيق React على المضيف المحلي
- كيفية إصلاح الخطأ "لا يمكن تحديث مكون أثناء عرض مكون مختلف" في React
- هل يمكنني استخدام خطافات React داخل شرطي؟
- استخدام useState مع كائن: كيفية التحديث
- كيفية تحريك الكتل البرمجية باستخدام React و Tailwind
- React ، ركز عنصرًا في React عند إضافته إلى DOM
- رد فعل وتحرير النص عند النقر المزدوج