تخطَّ إلى المحتوى

useReducer()

إدارة حالة معقّدة عبر دالة reducer useReducer()

useReducer بديل لـ useState لإدارة حالة معقّدة عبر دالة reducer تستقبل الحالة والإجراء (action) وتُرجع الحالة الجديدة.

useReducer(reducer, initialState) يُرجع [state, dispatch]. بدل استدعاء دالة تحديث مباشرة، تستدعي dispatch(action) — وReact يمرّر الحالة الحالية والإجراء لدالة reducer التي تُقرّر الحالة التالية وتُرجعها.

يُفضَّل على useState عندما تعتمد الحالة التالية على منطق معقّد بعدة حالات فرعية مترابطة، أو عندما يُحدَّث نفس نوع الحالة من أماكن متعددة بأنواع إجراءات مختلفة — يجمع منطق التحديث في مكان واحد بدل تشتيته.

الصياغة

const [state, dispatch] = useReducer(reducer, initialState);

function reducer(state, action) {
  switch (action.type) {
    case "...": return { ...state };
    default: return state;
  }
}

📄 مثال

function reducer(state, action) {
  switch (action.type) {
    case "increment": return { count: state.count + 1 };
    case "decrement": return { count: state.count - 1 };
    default: return state;
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, { count: 0 });
  return (
    <>
      <p>{state.count}</p>
      <button onClick={() => dispatch({ type: "increment" })}>+</button>
      <button onClick={() => dispatch({ type: "decrement" })}>-</button>
    </>
  );
}

أهم المعاملات

المعاملالوظيفة
reducerدالة (state, action) => newState خالية من التأثيرات الجانبية
initialStateالحالة الابتدائية
dispatchدالة لإطلاق إجراء يُمرَّر إلى reducer

💡 نصائح عملية

  • اجعل reducer دالة نقية (pure) دائمًا — بلا استدعاءات شبكة أو تأثيرات جانبية بداخلها
  • دمجه مع useContext يعطي نمطًا شبيهًا بـ Redux المصغّر دون مكتبة خارجية

⚠️ أخطاء شائعة

  • وضع منطق غير متزامن (fetch مثلًا) داخل reducer نفسه — يجب أن يبقى محضًا، ضع الـ async في useEffect أو Action
  • استخدامه لحالة بسيطة مستقلّة لا تحتاج منطقًا معقّدًا — useState أبسط وأوضح هناك

خصائص ذات صلة

🎓 تريد فهم الصورة الكاملة خطوة بخطوة؟ ابدأ من مسار REACT الكامل بالعربي.