محتويات الدورة

React / سلوك تطبيق منسق / الدرس 9

Reducers وContext وملكية الحالة

نمذج الانتقالات المتماسكة بدوال نقية وشارك قيما محددة النطاق دون مخزن عام مبهم.

وقت القراءة التقريبي: 3 دقيقةتاريخ مراجعة المحتوى
في هذه الصفحة

أهداف الدرس

  • وضع الحالة بمالكها المناسب
  • حفظ ثابت بانتقال واحد
  • مراجعة العمر وحدود الاختبار

وضع الحالة بمالكها المناسب

ارفع المشترك لأقرب مالك ينسقه ولا تكرر نسخه بين الأشقاء، وأبق المحلي محليا. تنقل Context القيمة في شجرة دون كل الوسائط لكنها لا تقرر الملكية والعمر والحفظ. حدد عمر المزود والمستهلكين؛ فقد تربط قيمة ضخمة متغيرة ميزات غير مترابطة.

تصف reducer انتقالا

تمرر useReducer الحالة والفعل لدالة نقية تعيد التالي. سم أحداث المجال لا تعليمات تعديل داخلي مطلقة. تحقق من الثوابت واحفظ المدخل ولا تنفذ طلبات أو عشوائية أو تعديلا خارجيا. ينشئ المعالج المعرف أو ينسق الأثر ثم يرسل فعلا كاملا. لا تضمن الدالة الصحة لكنها تجمع القواعد باختبار واضح.

حفظ ثابت بانتقال واحد

ينمذج المثال عدادا لا ينزل عن صفر ويعيد القديم عند المنع، فيحفظ الثابت دون محدثين. ليس نظام حجز؛ يفرض الخادم السعة والتفويض. تختبر الدالة الصفر والموجب والفعل المجهول دون متصفح ثم تختبر الواجهة النية والعدد.

jsx وحدة مكون — تتطلب مضيف React الموضح بالمقرر
import { useReducer } from "react";
export function reducer(count, action) { if (action.type === "add") return count + 1; if (action.type === "remove") return Math.max(0, count - 1); return count; }
export default function App() { const [count, dispatch] = useReducer(reducer, 0); return <main><h1>Seats: {count}</h1><button type="button" onClick={() => dispatch({ type: "add" })}>Add</button><button type="button" onClick={() => dispatch({ type: "remove" })}>Remove</button></main>; }
الناتج المتوقع
Initial: Seats: 0. Remove at zero: Seats: 0. Add: Seats: 1.

يفرض انتقال نقي الحد ولا يغير الحذف الصفر.

توفير قيمة قراءة محددة النطاق

يقدم المثال سياق ثيمة لمستهلك داخلي. تتوافق .Provider مع 18 وتبقى صالحة في 19 ذات الصياغة الأحدث أيضا. يستخدم الافتراضي عند غياب المزود لا عند undefined صريحة. وضح المزود الإلزامي وافصل السياقات إذا اختلف المستهلكون ومعدلاتهم؛ فالنقل لا يبرر دمج كل المجال.

jsx وحدة مكون — تتطلب مضيف React الموضح بالمقرر
import { createContext, useContext } from "react";
const Theme = createContext("default");
function Badge() { return <p>Theme: {useContext(Theme)}</p>; }
export default function App() { return <main><h1>Scoped context</h1><Theme.Provider value="night"><Badge /></Theme.Provider></main>; }
الناتج المتوقع
Scoped context
Theme: night

يقدم المزود الأقرب night ولا يستخدم الافتراضي لوجوده.

مراجعة العمر وحدود الاختبار

اختبر الانتقالات مستقلة والسياق ضمن شجرته. قد يعيد تركيب المزود الحالة ويحجب الداخلي الخارجي عمدا؛ افحص الحدود عند القدم والضبط المفاجئ. لا تتجاوز واجهة مكون لازمة لمجرد كراهية خاصية واحدة. يسهل التصميم الاكتشاف والاختبار بمزود صغير. يبقى التخزين والمخطط والترحيل والفشل والخصوصية حدودا منفصلة.

الأخطاء الشائعة وإصلاحها

تختلف قيم الأشقاء

لماذا يحدث؟
للحقيقة نسخ مستقلة.
كيف تصلحه؟
ارفعها لمالك منسق.
كيف تتجنب تكراره؟
حدد مصدر حقيقة.

تكرر reducer عملية خارجية

لماذا يحدث؟
تؤثر أثناء الحساب.
كيف تصلحه؟
احفظ النقاء وافصل الأثر.
كيف تتجنب تكراره؟
اختبر تكرار الحساب.

لا يستبدل الافتراضي undefined

لماذا يحدث؟
قدمها المزود الموجود صراحة.
كيف تصلحه؟
صحح قيمته أو افرض العقد.
كيف تتجنب تكراره؟
ميز غياب المزود والقيمة.

اختبر فهمك

1. صمم أفعال إضافة وحذف عربة دون استبدال اعتباطي.

اعرض الحل المشروح

استخدم itemAdded بالمعرف والكمية وitemRemoved بالمعرف، ودع الدالة تفرض القيود بثبات. ينقل المستدعي النية وتجمع الدالة القرار.

2. متى تبقى مسودة سريعة التغير خارج سياق ثيمة؟

اعرض الحل المشروح

حين لا يحتاج المستهلكون المسودة. أبقها بمالك النموذج وانقل ما يخص مسؤولية السياق فقط لتقليل الترابط والتحديث غير المرتبط.

أهم ما تعلمته

  • تسبق الملكية النقل.
  • تحسب reducers انتقالات نقية.
  • للسياق نطاق مزود وعمر.

المراجع الرسمية