الطفرات والتحديثات المتفائلة
تعلم كيفية تصميم عمليات كتابة خادم على أنها انتقالات حالة منسقة واستخدام التحديثات المتفائلة بحيث تبدو واجهة المستخدم فورية مع الحفاظ على صحتها وموثوقيتها.
تستقر معظم فرق React بمجرد حل مشكلة قراءة البيانات. يتم جلب البيانات وتخزينها مؤقتًا وتقسيمها إلى صفحات وعرضها بشكل متوقع. ولكن بمجرد السماح للمستخدمين بتغيير البيانات، مثل منشور أو تحديث ملف تعريف أو إعادة ترتيب قائمة، غالبًا ما يتراجع أداء البنية. تُعامل عمليات الكتابة على أنها لحظات حساسة وهشة في واجهة المستخدم: تُعطل الأزرار، وتظهر مؤشرات التحميل، وتنتظر أقسام كاملة استجابة خادم قبل إجراء أي تغيير.
يبدو هذا النمط "آمنًا"، لكنه يُثير نوعًا مختلفًا من المشاكل. تصبح واجهة المستخدم مُقيَّدة بالتأخير: كل تفاعل ينتظر الشبكة، حتى عندما يكون قصد المستخدم واضحًا. تومض القوائم لأن الفرق تُعيد جلب البيانات بشكل مُكثَّف بعد كل عملية كتابة. تفقد الحالة المشتركة تزامنها لأن مُكوِّنات مُتعددة تُحدِّث في أوقات مُختلفة. تُصبح معالجة الأخطاء مُدمِّرة؛ فالفشل غالبًا ما يعني هدم حالة واجهة المستخدم وإعادة بنائها من الصفر.
المشكلة الأعمق لا تقتصر على الأداء فحسب، بل تتعلق بملكية الحالة. في العديد من قواعد البيانات، لا يوجد لدى واجهة المستخدم اتفاقية واضحة لما يجب أن تمثله أثناء عملية الكتابة. هل التغييرpending ؟ هل هذاoptimistic ؟ هل هذاconfirmed بدون إجابة مشتركة على مستوى النظام، تقوم المكونات بإنشاء علامات محلية وحالة مؤقتة مخصصة، ويصبح العرض مرتبطًا بشكل وثيق بدورة حياة طلب بدلاً من نموذج البيانات.
يُعالج نموذج التعديل في React Query، وخاصةً التحديثات التفاؤلية، هذه الثغرة. فبدلاً من التعامل مع عمليات الكتابة كأحداث مُعطِّلة تُجمِّد واجهة المستخدم، يُعاملها كعمليات انتقال مُنسَّقة في حالة خادم . وتُصبح ذاكرة التخزين المؤقت هي المكان الذي تُدار فيه النية والافتراض والتأكيد والتراجع، بحيث يُمكن للمكونات عرض لقطة متسقة دون الحاجة إلى إدارة دقيقة لعملية الكتابة.
يوضح الرسم البياني أعلاه مقارنة بين خطين زمنيين. في الأول، يؤدي إجراء المستخدم إلى عملية كتابة، وتدخل واجهة المستخدم في حالة انتظار، ولا يتم تحديث الشاشة إلا بعد استجابة خادم . أما في الثاني، فيُطبّق التخزين المؤقت تحديثًا تفاؤليًا على الفور، وتعكس واجهة المستخدم التغيير مباشرةً، ثم تأتي استجابة خادم لاحقًا إما لتأكيد التغيير أو لإعادة التخزين المؤقت إلى حالته السابقة.
التعامل مع الطفرات كآلات حالة
تمثل عملية التغيير نية لتغيير حقيقة خادم . على عكس الاستعلامات التي تصف ما هو موجود، تصف عمليات التغيير ما ينبغي أن يصبح صحيح. ويتمثل القرار المعماري مفتاح في ما إذا كانت واجهة المستخدم تنتظر تأكيد هذه الحقيقة أم تمضي قدمًا بتفاؤل بناءً على النية.
تختار التحديثات المتفائلة الخيار الثاني. عند بدء عملية التغيير، يتم تحديث ذاكرة التخزين المؤقت فورًا لتعكس النتيجة المتوقعة. هذا يُنشئ لقطة متفائلة: نسخة مؤقتة من حالة خادم تفترض النجاح. يقوم React بالعرض بناءً على هذه اللقطة مباشرةً، مما يجعل واجهة المستخدم سريعة الاستجابة وحاسمة بدلاً من أن تكون مترددة.
في الوقت نفسه، يسجل المخزن المؤقت التغييرات ويحتفظ بنسخة مرجعية للحالة السابقة. عند استجابة خادم ، يحدث أحد أمرين: إذا نجح التغيير، يتم تأكيد الحالة المتفائلة أو استبدالها استجابة خادم الرسمية؛ أما إذا فشل، فيعود المخزن المؤقت إلى اللقطة السابقة بطريقة مركزية ومُحكمة. في كلا الحالتين، يتم تحديث جميع المشتركين بشكل متسق، لأن المخزن المؤقت، وليس المكونات الفردية، هو المسؤول عن عملية الانتقال.
يُغيّر هذا الإطار طريقة تفكيرنا في الأخطاء والتحميل. لم تعد الأخطاء عمليات إعادة ضبط كارثية، بل أصبحت تراجعًا عن افتراض متفائل. ولم يعد التحميل يعني "توقف واجهة المستخدم"، بل أصبح "النظام يتحقق من صحة حالة سبق عرضها". في React المتزامن، يتناسب هذا النموذج بشكل طبيعي: يبقى العرض دون انقطاع، وتبقى التفاعلات سريعة الاستجابة، وتصبح عمليات الكتابة خطوات متوقعة في آلة الحالة بدلًا من توقفات مُعطِّلة.
لقد قمنا بتأطير التغييرات على أنها تحولات في حالة إحداثيات ذاكرة التخزين المؤقت . الآن دعونا بناء تطبيقًا صغيرًا ...