React Thunk وReact Saga عبارة عن مكتبات وسيطة للتعامل مع التأثيرات الجانبية في تطبيقات React، خاصة لإدارة العمليات غير المتزامنة مثل استدعاءات واجهة برمجة التطبيقات (API). يتم استخدام كلاهما بشكل شائع مع Redux ولكنهما يخدمان أغراضًا وأساليب مختلفة قليلاً.
الرد السريع
1. نظرة عامة:
React Thunk هو برنامج وسيط يسمح لك بكتابة منشئي الإجراءات الذين يعرضون الوظائف بدلاً من كائنات الإجراء. يعد هذا مفيدًا للتعامل مع العمليات غير المتزامنة مثل طلبات API أو المنطق المتزامن المعقد (مثل الإرسال المشروط للإجراءات). تتلقى الوظيفة التي تم إرجاعها الإرسال وgetState كوسيطتين، مما يسمح لك بإرسال إجراءات أخرى أو الوصول إلى الحالة الحالية داخل الوظيفة.
2. المفاهيم الأساسية:
-
البرمجيات الوسيطة: Thunk هو برنامج وسيط يعمل على توسيع قدرة المتجر على التعامل مع الوظائف (أي، thunks).
-
الإجراءات غير المتزامنة: باستخدام Thunk، يمكنك تأخير إرسال إجراء ما أو إرساله بشكل مشروط بناءً على حالة أو منطق معين.
-
بسيط: يعتبر Thunk واضحًا نسبيًا، مما يجعله سهل الاستخدام في معظم حالات الاستخدام.
3. كيفية العمل:
- عادةً، يقوم منشئو الإجراءات بإرجاع كائنات (إجراءات) JavaScript عادية.
- باستخدام Thunk، يمكن لمنشئ الإجراء إرجاع وظيفة ("thunk") التي تتلقى الإرسال وgetState. داخل هذه الوظيفة، يمكنك تنفيذ منطق غير متزامن (على سبيل المثال، جلب البيانات من واجهة برمجة التطبيقات) ثم إرسال الإجراء الحقيقي.
4. مثال:
إليك مثال أساسي لكيفية استخدام redux-thunk في تطبيق React:
// Action Creator with Thunk
export const fetchUser = () => {
return async (dispatch) => {
dispatch({ type: 'FETCH_USER_REQUEST' });
try {
const response = await fetch('/api/user');
const data = await response.json();
dispatch({ type: 'FETCH_USER_SUCCESS', payload: data });
} catch (error) {
dispatch({ type: 'FETCH_USER_FAILURE', payload: error });
}
};
};
5. مزايا Thunk:
-
البساطة: من السهل فهم وتنفيذ Thunk.
-
مساحة صغيرة: إنها خفيفة الوزن ولا تتطلب تكوينات معقدة.
-
التحكم المباشر في الإرسال: لديك المزيد من التحكم في متى وكيف يتم إرسال الإجراءات.
6. العيوب:
-
يصعب قياسه: بالنسبة للتدفقات المعقدة غير المتزامنة، يمكن أن يصبح Thunk فوضويًا، مع المنطق المتداخل والكثير من مكالمات الإرسال.
-
بنية أقل: لا يفرض Thunk بنية معينة لإدارة الآثار الجانبية، مما قد يؤدي إلى تعليمات برمجية غير متناسقة إذا لم يتم التعامل معها بشكل صحيح.
قصة التفاعل
1. نظرة عامة:
React Saga هو برنامج وسيط يسمح لك بالتعامل مع الآثار الجانبية بطريقة أكثر تنظيمًا باستخدام وظائف المولد. بدلاً من إرجاع وظائف مثل Thunk، فإنه يستخدم نظام "التأثير" لإدارة العمليات غير المتزامنة والتحكم في تدفق المنطق الخاص بك. Sagas عبارة عن عمليات خلفية طويلة الأمد يمكنها الاستماع إلى الإجراءات المرسلة وتنفيذ تأثيرات جانبية مثل استدعاءات واجهة برمجة التطبيقات وجلب البيانات ومهام أخرى.
2. المفاهيم الأساسية:
-
وظائف المولد: يتم تنفيذ الملحمات باستخدام وظائف المولد ES6 (الوظيفة*)، والتي تسمح لك بكتابة تعليمات برمجية غير متزامنة تبدو متزامنة.
-
المراقبون والعمال: غالبًا ما يتم تقسيم الملاحم إلى ملاحم "المراقب" (التي تستمع إلى الإجراءات المرسلة) وملاحم "العامل" (التي تتعامل مع الآثار الجانبية).
-
الأخذ والوضع والاتصال: يوفر Redux-Saga منشئي التأثيرات (الأخذ والوضع والاتصال وما إلى ذلك) للتحكم في وقت تشغيل التأثيرات الجانبية وإجراءات الإرسال واستدعاء واجهات برمجة التطبيقات.
3. كيفية العمل:
- مع Redux-Saga، يمكنك تحديد الملحمات (مهام الخلفية طويلة الأمد) المسؤولة عن التعامل مع الآثار الجانبية.
- تتم كتابة القصص الملحمية عادةً كوظائف منشئة وتؤدي إلى تأثيرات مثل الاتصال (لاستدعاء الوظائف) والوضع (لإرسال الإجراءات).
- يمكن لـ Sagas أيضًا انتظار إجراءات محددة من خلال اتخاذ أو الاستماع إلى أي إجراءات باستخدام takeEvery أو takeLatest.
4. مثال:
إليك مثال أساسي لكيفية استخدام redux-saga:
import { call, put, takeLatest } from 'redux-saga/effects';
// Worker saga: will be fired on FETCH_USER_REQUEST actions
function* fetchUser(action) {
try {
const response = yield call(fetch, '/api/user');
const data = yield response.json();
yield put({ type: 'FETCH_USER_SUCCESS', payload: data });
} catch (e) {
yield put({ type: 'FETCH_USER_FAILURE', message: e.message });
}
}
// Watcher saga: spawns a new fetchUser task on each FETCH_USER_REQUEST
function* mySaga() {
yield takeLatest('FETCH_USER_REQUEST', fetchUser);
}
export default mySaga;
5. مزايا Redux-Saga:
-
أفضل للتأثيرات الجانبية المعقدة: يعتبر نهج Saga القائم على التأثير أكثر قابلية للتطوير وملاءمًا لإدارة التدفقات غير المتزامنة المعقدة (على سبيل المثال، التعامل مع عمليات إعادة المحاولة، أو التراجع، أو استدعاءات واجهة برمجة التطبيقات المتتالية).
-
قابلة للاختبار: من السهل اختبار القصص الملحمية لأنها مبنية على وظائف المولد.
-
تصريحي: استخدام التأثيرات يجعل من الواضح ما هي الآثار الجانبية التي ستحدث، مما يجعل التدفق أكثر قابلية للتنبؤ به.
-
الإلغاءات والتسلسلات: تسهل Saga إلغاء المهام الجارية أو فرض تدفقات تسلسلية للأحداث (مثل انتظار إجراءات متعددة).
6. العيوب:
-
منحنى التعلم الأكثر حدة: قد يكون من الصعب على المبتدئين فهم استخدام وظائف المولد ونمط الملحمة العام.
-
التكاليف العامة: بالنسبة للتطبيقات الصغيرة، قد يبدو الأمر مبالغًا فيه مقارنة بالحلول الأبسط مثل Thunk.
-
مطول: تميل القصص الملحمية إلى تضمين المزيد من التعليمات البرمجية المعيارية مقارنةً بـ Thunk.
المقارنة: React Thunk مقابل React Saga
وجه |
رد فعل ثانك |
ملحمة التفاعل |
---|
مفهوم |
إرجاع الوظائف في منشئي الإجراءات |
يستخدم وظائف المولد للآثار الجانبية |
منحنى التعلم |
أسهل في التعلم والاستخدام |
منحنى التعلم العالي بسبب المولدات |
التدفق غير المتزامن |
يتعامل مع المنطق البسيط غير المتزامن |
أفضل لعمليات سير العمل غير المتزامنة المعقدة |
هيكل الكود |
بنية أقل، يمكن أن تصبح فوضوية في التطبيقات الكبيرة |
يوفر نهجًا واضحًا ومنظمًا |
الاختبار |
قد يكون الاختبار أكثر صعوبة |
أسهل للاختبار بسبب المولدات |
حالات الاستخدام |
منطق غير متزامن بسيط، طلبات واجهة برمجة التطبيقات |
التدفقات المعقدة (مثل التسلسلات وإعادة المحاولة) |
أداء |
خفيف الوزن |
أكثر قوة، ولكن أكثر قليلاً |
متى يتم استخدام أي منها؟
-
استخدم React Thunk إذا:
- يحتوي تطبيقك على احتياجات غير متزامنة بسيطة نسبيًا، مثل طلبات واجهة برمجة التطبيقات الأساسية والإرسال بناءً على الشروط.
- أنت تريد حلاً خفيف الوزن وسهل الفهم بدون الكثير من القواعد النمطية.
-
استخدم React Saga إذا:
- تحتاج إلى إدارة التدفقات غير المتزامنة الأكثر تعقيدًا، مثل عمليات إعادة المحاولة، أو تسلسل الإجراءات، أو ظروف السباق، أو المهام المتعددة التي تعتمد على بعضها البعض.
- أنت تفضل النهج التعريفي وتريد تحكمًا أفضل في الآثار الجانبية.
- يتطلب تطبيقك إمكانية اختبار أفضل وإمكانية صيانة التعليمات البرمجية على المدى الطويل.