Redux هو حاوية حالة يمكن التنبؤ بها لتطبيقات جافا سكريبت قائمة على نمط تدفق البيانات أحادي الاتجاه (Unidirectional Data Flow).
المفاهيم الأساسية وإنشاء المخزن (Store)
import { createStore } from 'redux';
// دالة Reducer: دالة نقية تحسب الحالة التالية
function counterReducer(state = { value: 0 }, action) {
switch (action.type) {
case 'counter/incremented':
return { value: state.value + 1 };
case 'counter/decremented':
return { value: state.value - 1 };
default:
return state;
}
}
// إنشاء المخزن
const store = createStore(counterReducer);
// الاشتراك في تغييرات الحالة
const unsubscribe = store.subscribe(() => {
console.log('الحالة الحالية:', store.getState());
});
// إرسال الإجراءات
store.dispatch({ type: 'counter/incremented' }); // { value: 1 }
store.dispatch({ type: 'counter/decremented' }); // { value: 0 }
منشئو الإجراءات والبرمجيات الوسيطة (Middleware)
// منشئ إجراء Action Creator
const incrementBy = (amount) => ({
type: 'counter/incrementBy',
payload: amount
});
// نمط البرمجيات الوسيطة (لتسجيل السجلات أو العمليات غير المتزامنة)
const loggerMiddleware = (storeAPI) => (next) => (action) => {
console.log('جاري إرسال الإجراء:', action);
const result = next(action);
console.log('الحالة التالية:', storeAPI.getState());
return result;
};
خطافات React Redux (useSelector و useDispatch)
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
export function Counter() {
const count = useSelector((state) => state.value);
const dispatch = useDispatch();
return (
<div>
<span>Count: {count}</span>
<button onClick={() => dispatch({ type: 'counter/incremented' })}>
+
</button>
</div>
);
}
مجموعة أدوات Redux الحديثة (Redux Toolkit - RTK)
تستخدم تطبيقات Redux الحديثة مجموعة أدوات Redux Toolkit لتبسيط المنطق وتقليل الكود المكرر:
import { createSlice, configureStore } from '@reduxjs/toolkit';
const counterSlice = createSlice({
name: 'counter',
initialState: { value: 0 },
reducers: {
increment: (state) => { state.value += 1; },
decrement: (state) => { state.value -= 1; }
}
});
export const { increment, decrement } = counterSlice.actions;
export const store = configureStore({ reducer: counterSlice.reducer });