- بواسطة x32x01 ||
لو بتشتغل React أكيد قابلتك مشكلة Data Fetching
سواء Login، Get Todos، أو أي API Call 👨💻
دايمًا نفس الأسئلة بتطلع:
createAsyncThunk + extraReducers 🚀
بتستخدمها علشان تعمل Async Logic زي الاتصال بـ API.
أنت بتديها:
RTK بيولّدلك أوتوماتيك 3 حالات:
وده بيديك أدوات قوية جدًا 🔥
أهمهم:
وده بيخلّي الـ reducer يتعامل مع الخطأ بسهولة.
هتلاقي مكان اسمه extraReducers
هنا بتقوله:
لو الـ async action دخل في حالة pending أو fulfilled أو rejected
اعمل التغييرات دي في الـ state
الكومبوننت يقدر:
لو اليوزر عمل Login أي صفحة تانية (Navbar - Profile - Dashboard)
تشوف نفس الداتا من غير Props Drilling 😍
بعد ما كان صداع في Redux العادي
يبقى 3 خطوات واضحة 👌
1️⃣ عرّف thunk
2️⃣ ضيف extraReducers
3️⃣ استخدم dispatch + selector
🚀 أبسط - أنضف - أقوى
سواء Login، Get Todos، أو أي API Call 👨💻
دايمًا نفس الأسئلة بتطلع:
- أعرف إزاي الطلب بدأ؟ (Loading) ⏳
- أحفظ فين الداتا اللي رجعت؟ (Data) 📦
- أتعامل إزاي مع الخطأ؟ (Error) ❌
- وإزاي أخلي الحالة دي متاحة في أي مكان في التطبيق؟ 🤯
createAsyncThunk + extraReducers 🚀
🟢 يعني إيه createAsyncThunk؟
createAsyncThunk دي دالة جاهزة في Redux Toolkitبتستخدمها علشان تعمل Async Logic زي الاتصال بـ API.
أنت بتديها:
- اسم للـ action (مثلاً: auth/logIn)
- ودالة فيها منطق الطلب (API Call)
RTK بيولّدلك أوتوماتيك 3 حالات:
- Pending → أول ما الطلب يبدأ
- Fulfilled → لما الطلب ينجح
- Rejected → لما يحصل Error
🟡 إيه هو thunkAPI؟
جوه createAsyncThunk بيجيلك كائن اسمه thunkAPIوده بيديك أدوات قوية جدًا 🔥
أهمهم:
- dispatch → تبعت actions إضافية
- getState → تجيب الـ state الحالي
- rejectWithValue → أهم حاجة 👑
وده بيخلّي الـ reducer يتعامل مع الخطأ بسهولة.
🔵 استخدام extraReducers في Redux Toolkit
لما تعمل slice في RTKهتلاقي مكان اسمه extraReducers
هنا بتقوله:
لو الـ async action دخل في حالة pending أو fulfilled أو rejected
اعمل التغييرات دي في الـ state
مثال عملي:
- pending
- loading = true
- مسح أي error قديم
- fulfilled
- loading = false
- تخزين الداتا (user / token)
- rejected
- loading = false
- تخزين رسالة الخطأ
💻 مثال كود عملي (Redux Toolkit)
JavaScript:
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
import axios from 'axios';
export const logIn = createAsyncThunk(
'auth/logIn',
async (userData, thunkAPI) => {
try {
const res = await axios.post('/api/login', userData);
return res.data;
} catch (err) {
return thunkAPI.rejectWithValue(err.response.data.message);
}
}
);
const authSlice = createSlice({
name: 'auth',
initialState: {
loading: false,
user: null,
error: null,
},
extraReducers: (builder) => {
builder
.addCase(logIn.pending, (state) => {
state.loading = true;
state.error = null;
})
.addCase(logIn.fulfilled, (state, action) => {
state.loading = false;
state.user = action.payload;
})
.addCase(logIn.rejected, (state, action) => {
state.loading = false;
state.error = action.payload;
});
},
});
export default authSlice.reducer;
🔴 إزاي أستخدمه جوه الكومبوننت؟
من جوه أي React Component 👇- تستخدم useDispatch علشان تبعت الـ thunk
- تستخدم useSelector علشان تقرا الـ state
JavaScript:
const dispatch = useDispatch();
const { loading, user, error } = useSelector(state => state.auth);
const handleLogin = () => {
dispatch(logIn(formData));
}; - يعرض Loading... أثناء الطلب ⏳
- يطلع رسالة خطأ ❌
- يعرض بيانات اليوزر لما الـ login ينجح ✅
🟣 ليه الـ state متاح في كل الكومبوننتات؟
السبب هو Single Source of Truth 🧠- الـ Redux Store متحطوط في <Provider>
- أي كومبوننت تحته يقدر يوصل لنفس الـ state
لو اليوزر عمل Login أي صفحة تانية (Navbar - Profile - Dashboard)
تشوف نفس الداتا من غير Props Drilling 😍
✨ النتيجة النهائية
- createAsyncThunk → إدارة الـ async بسهولة
- extraReducers → تحكم في Loading / Data / Error
- dispatch + useSelector → تعامل بسيط من الكومبوننت
- State مركزي متاح في أي مكان
📌 الخلاصة
Redux Toolkit خلّى الـ Data Fetchingبعد ما كان صداع في Redux العادي
يبقى 3 خطوات واضحة 👌
1️⃣ عرّف thunk
2️⃣ ضيف extraReducers
3️⃣ استخدم dispatch + selector
🚀 أبسط - أنضف - أقوى