إذا كنت تعمل مع React بشكل يومي، فستكتشف عاجلاً أم آجلاً أن إتقان استخدام useState و useEffect يُحدث فرقًا كبيرًا بين مكون "يعمل بشكل متقطع" وواجهة متينة وقابلة للصيانة وسهلة التصحيح. تبدو كلتا الخطافين بسيطتين في البداية، ولكن بمجرد البدء في إجراء طلبات HTTP أو الاشتراكات أو المؤقتات، تنشأ الشكوك، وتتكرر التأثيرات في حلقات مفرغة، وتصبح الحالات "قديمة".
سنرى في السطور التالية كيفية استخدام useState و useEffect بشكل صحيح في React، من الأساسيات إلى الأنماط المتقدمةتجمع هذه الدورة بين أفضل الممارسات لتحسين الأداء، وإدارة التبعيات، وتنظيف التأثيرات، والاستخدام مع واجهات برمجة التطبيقات الخارجية، وبعض الحيل لتجنب الأخطاء الشائعة. الهدف هو أن تتمكن في نهاية الدورة من قراءة أي مكون باستخدام الخطافات وفهم ما يحدث فيه، والأهم من ذلك، أن تتمكن من تصميم مكوناتك الخاصة دون الخوف من إتلاف أي شيء.
ما هما بالضبط useState و useEffect ومتى يجب استخدامهما؟
بدأ تطبيق React باستخدام Hooks بدءًا من الإصدار 16.8 لإدارة حالة ومنطق دورة حياة المكونات الوظيفية دون استخدام الفئات. الهدف هو تمكينك من إنشاء منطق قابل لإعادة الاستخدام بشكل تصريحي، بالاستفادة من لغة جافا سكريبت نفسها (الإغلاقات، الدوال النقية، إلخ).
الخطاف استخدام يُستخدم لإضافة الحالة المحلية للمكون الوظيفيبدلاً من امتلاك هذه الحالة y this.setStateتعلنون أنكم زوجان [valor, setValor] سيربط React ترتيب استدعاءات الخطافات في ذلك المكون بتلك الحالة. وسيكون لكل عملية عرض "نسخة" خاصة بها من تلك الحالة.
من جانبها، useEffect هو الخطاف المصمم للآثار الجانبية.: الكود الذي يتم تنفيذه بعد أن يقوم React بالرسم في DOM وهذا يتفاعل مع الأنظمة الخارجية: طلبات البيانات، واشتراكات WebSocket، والوصول إلى localStorage، والتلاعب بالنوافذ، والمؤقتات مع setInterval o setTimeout، الخ.
على الرغم من أنه يقال غالباً أن يُعادل useEffect كلاً من componentDidMount و componentDidUpdate و componentWillUnmount مجتمعةمن الأدق الاعتقاد بأنه يصف "ما الذي يجب مزامنته مع التصميم الخارجي بعد كل عملية عرض؟"ثم، تحدد مصفوفة التبعية عندما تمت عملية المزامنة هذه.

useState: إدارة الحالة المحلية بشكل تصريحي
الخطاف استخدام يتم الإعلان عنه في أعلى المكون ويتلقى القيمة الأوليةتُعيد هذه الدالة مصفوفةً تحتوي على عنصرين: القيمة الحالية ودالة لتحديثها. فعلى سبيل المثال، يُعرَّف شيء بسيط كالعداد على النحو التالي:
مثال أساسي لاستخدام الحالة:
import { useState } from "react";
دالة العداد الأساسي() {
const [count, setCount] = useState(0);
const increment = () => {
setCount(count + 1);
};
إرجاع (
<div>
لقد ضغطت على الزر {count} مرات
اضغطني
</div>
);
}
في كل عرض، يمثل العدد الحالة المقابلة لهذا العرض المحدد.عند الاتصال setCountيُجدول React عملية عرض جديدة بالقيمة المُحدَّثة. إذا كان التحديث يعتمد على القيمة السابقة، فمن الأفضل استخدام أسلوب الدالة.
setCount(prev => prev + 1);
تتجنب هذه الصيغة المشاكل عند ربط عدة تحديثات معًا، لأن يضمن React أن prev هي آخر قيمة مستقرةحتى في الوضع المتزامن.
useEffect: فهم دورة حياته ومجموعة تبعياته
إن توقيع خطاف التأثير بسيط للغاية: useEffect(efecto, dependencias?)الوسيط الأول هو دالة إعداد، تُنفَّذ بعد رسم DOM. ويمكن لهذه الدالة، اختيارياً، أن تُعيد دالة تنظيف أخرى يستدعيها React قبل إعادة تشغيل التأثير أو عند إلغاء تحميل المكون.
يكمن مفتاح استخدام useEffect بفعالية في فهم مجموعة التبعيات.تشير هذه المصفوفة إلى القيم "التفاعلية" التي يعتمد عليها منطق التأثير: الخصائص، والحالات، والمتغيرات أو الدوال المُعرَّفة داخل المكون. يقارن React التبعيات الحالية بتلك الخاصة بالعرض السابق باستخدام Object.isفي حال حدوث أي تغيير، قم أولاً بتشغيل عملية التنظيف السابقة ثم قم بتكوين التأثير الجديد.
بحسب طريقة كتابة تلك المصفوفة، ستحصل على سلوكيات مختلفة:
- لا يوجد حجة ثانيةيتم تنفيذ التأثير بعد كل إعلان.
- مصفوفة فارغة []يتم تشغيل التأثير تلقائيًا مرة واحدة بعد العرض الأول (الوضع "componentDidMount" و "componentWillUnmount").
- مصفوفة تحتوي على التبعيات [أ، ب]يتم تنفيذ التأثير بعد العرض الأول و في كل مرة يتغير فيها أحد تلك التبعيات.
مثال نموذجي جداً: قم بتحديث عنوان المستند باستخدام عدادإنه المكافئ الوظيفي الحديث لنمط الفئة الكلاسيكي مع componentDidMount + componentDidUpdate.
مثال على استخدام useEffect لمزامنة عنوان المستند:
import { useState, useEffect } from "react";
دالة CounterWithTitle() {
const [count, setCount] = useState(0);
استخدم التأثير(() => {
document.title = `لقد ضغطت على الزر ${count} مرات`;
}، [عدد])؛
إرجاع (
<div>
تم الضغط على الزر {count} مرة
setCount(count + 1)}>ادفعني
</div>
);
}
في هذه الحالة، التبعية هي countويجب أن يكون موجوداً في المصفوفة، بغض النظر عن أي شيء.لأنه يُستخدم ضمن التأثير. إذا حاولت حذفه، eslint-plugin-react-hooks سوف يحذرك؛ وإذا أجبرت برنامج التدقيق على الصمت، فسوف ينتهي بك الأمر بأخطاء يصعب اكتشافها حيث لا يتطابق العنوان مع القيمة الفعلية للعداد.

التأثيرات غير المتعلقة بالتنظيف: منطق لا يلزم تنفيذه إلا بعد العرض.
هناك فئة من التأثيرات التي لا تتطلب تنظيفًا خاصًاهذه هي تلك التي "تفعل شيئًا ثم تنساه": تسجيل البيانات عبر وحدة التحكم، تعديل عنوان المستند، إجراء طلب HTTP لمرة واحدة، قياس شيء ما مرة واحدة فقط، إلخ.
في عالم الطبقات الاجتماعية، تم توزيع هذا المنطق بين componentDidMount y componentDidUpdateغالباً ما يكون ذلك مصحوباً بتكرار في التعليمات البرمجية. باستخدام الخطافات، يختفي هذا التكرار لأن يمكن لـ useEffect واحد التعامل مع كل من العرض الأولي والتحديثات..
مثال بسيط على تأثير بدون استخدام مواد التعقيم: الحصول على موقع المستخدم باستخدام واجهة برمجة تطبيقات تحديد الموقع الجغرافي للمتصفح واحفظه في الحالة التالية:
import { useState, useEffect } from "react";
دالة UserLocation() {
const [latitude, setLatitude] = useState(0);
const [length, setLength] = useState(0);
استخدم التأثير(() => {
إذا لم تكن خاصية تحديد الموقع الجغرافي (navigator.geolocation) {
console.log("المتصفح لا يدعم تحديد الموقع الجغرافي");
العودة؛
}
navigator.geolocation.getCurrentPosition((pos) => {
setLatitude(pos.coords.latitude.toFixed(0));
setLength(pos.coords.longitude.toFixed(0));
})؛
}, []);
في هذه الحالة، نريد فقط طلب الموقع مرة واحدة، عند تحميل المكون.لذا، فإن مصفوفة التبعيات فارغة: لا يوجد ما قد يُعيد تفعيل التأثير. لا حاجة للتنظيف لأننا لم نترك أي فترات زمنية أو اشتراكات أو مستمعين نشطين.
ومن الأمثلة الشائعة الأخرى على التأثير الذي لا يمكن إصلاحه ما يلي: سجل أو أداة تتبع تحليلية عند تغيير معلومات معينةعلى سبيل المثال، تسجيل غرفة الدردشة التي يتواجد فيها المستخدم أو عدد العناصر الموجودة في سلة التسوق الخاصة به، طالما لم يتم الحفاظ على اتصال مباشر مرتبط بهذا الحدث.
آثار التعقيم: الاشتراكات، والفترات الزمنية، وتسرب الذاكرة
الفئة الرئيسية الأخرى هي آثار تحتاج إلى تنظيفيحدث ذلك عادة عندما تقوم بإنشاء شيء ما ينبغي أن يكون قطع الاتصال أو الإلغاء عند تغيير التبعيات أو إلغاء تحميل المكون: اشتراكات واجهة برمجة التطبيقات، ومستمعو الأحداث العامة، والمؤقتات، ومآخذ الويب، وما إلى ذلك.
النمط هو نفسه دائماً: ضمن التأثير، تقوم بتهيئة المورد وإرجاع دالة تقوم بإلغاء ذلك.سيقوم React باستدعاء وظيفة التنظيف هذه قبل تشغيل التأثير مرة أخرى وعندما يختفي المكون من DOM.
مثال كلاسيكي: عداد يزيد تلقائيًا على فترات زمنية محددة.
import { useState, useEffect } from "react";
const AutomaticCounter = () => {
const [counter, setCounter] = useState(0);
استخدم التأثير(() => {
const interval = setInterval(() => {
console.log("الفاصل الزمني...");
setCounter((c) => c + 1);
} ، 2000) ؛
return () => {
console.log("فترة المسح");
clearInterval(interval);
};
}, []);
يعود {عداد} ؛
};
هنا، يتم إنشاء الفاصل الزمني عند تحميل المكون وحذفه عند إلغاء تحميله. إذا نسيت استدعاء clearInterval, ستستمر الفترة الزمنية في العمل حتى لو لم يعد المكون معروضًا.مما يتسبب في تسرب الذاكرة وتحديثات الحالة على المكونات المفككة.
نمط آخر شائع جداً هو الاشتراك في الأحداث العالميةكما resize de window o keydown en document:
import { useEffect } from "react";
دالة GlobalEvents() {
استخدم التأثير(() => {
const handleResize = () => {
console.log("تم تغيير حجم النافذة");
};
const handleKeyDown = (event) => {
console.log(«تم الضغط على مفتاح», event.key);
};
window.addEventListener("resize", handleResize);
document.addEventListener("keydown", handleKeyDown);
return () => {
window.removeEventListener("resize", handleResize);
document.removeEventListener("keydown", handleKeyDown);
};
}, []);
يعود الاستماع إلى الأحداث العالمية ;
}
La التنظيف يترك النظام تمامًا كما كان قبل تثبيت المكونهذا التماثل بين الإعداد والتنظيف أمر أساسي، خاصة بالنظر إلى أنه في وضع التطوير الصارم، يمكن لـ React تشغيل دورة إضافية من الإعداد → التنظيف → الإعداد لاكتشاف الأخطاء.
طلبات HTTP باستخدام useEffect و useState: دليل خطوة بخطوة
أحد الاستخدامات الأكثر شيوعًا لـ استخدام التأثير es تحميل البيانات من واجهة برمجة التطبيقات عند تحميل المكون وتخزين النتيجة في حالة مع استخدامهناك "وصفة" عملية للغاية يمكنك إعادة استخدامها في كل مرة تقريبًا:
- يبدأ المكون في وضع "التحميل". مع حالة نوع
isLoading. - قم بإجراء الطلب داخل useEffect مباشرة بعد أن يقوم React برسم المكون.
- احفظ الإجابة في الحالة والعلامة التجارية
isLoadingكماfalseعندما أنتهي. - العرض المشروط يظهر مؤشر تحميل أو رسالة أثناء التحميل
isLoadingبحرtrueوالبيانات عندما تصبح جاهزة.
مثال كامل: تطبيق يعرض جروًا عشوائيًا باستخدام واجهة برمجة تطبيقات الكلاب (Dog API)..
import { useState, useEffect } from "react";
دالة RandomDog() {
const [imageUrl, setImageUrl] = useState(null);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState(null);
استخدم التأثير(() => {
const fetchDog = async () => {
محاولة {
setIsLoading(true);
setError(null);
const response = await fetch(«https://dog.ceo/api/breeds/image/random»);
إذا لم تكن الاستجابة ناجحة (response.ok) {
throw new Error(«خطأ HTTP» + response.status);
}
بيانات const = wait response.json () ؛
setImageUrl(data.message);
} قبض (يخطئ) {
setError(err.message);
} أخيراً {
setIsLoading(false);
}
};
fetchDog();
}, []);
إذا (هو التحميل) {
يعود جارٍ الشحن… ;
}
إذا (خطأ) {
يعود خطأ: {error} ;
}
إرجاع (
<div>
</div>
);
}
لاحظ أنه تم التحقق منه response.ok للتمييز بين الاستجابة الصحيحة (الرموز 200-299) وأخطاء HTTPلا يرفض Fetch الوعود إلا في حالة حدوث أعطال في الشبكة، لذا إذا لم تتحقق... ok قد تعتقد أن "كل شيء على ما يرام" حتى مع وجود 500.
يمكن تطبيق هذا النمط نفسه على الطلبات التي تعتمد على الخصائص. على سبيل المثال، إذا كنت ترغب في عرض بيانات مستخدم معين بناءً على userId هذا ما يأتي من الأعلى، ستستخدم هذه الخاصية كاعتمادية للتأثير لـ قم بتحديث البيانات في كل مرة تتغير فيها.
الطلبات التي تعتمد على الدعائم والإلغاء الآمن أثناء التفكيك
عندما يعتمد عنوان URL أو هوية البيانات المراد تحميلها على خاصية (على سبيل المثال، أعد تحميل صفحة المستخدم إذا طرأ تغيير props.userId), مهم:
- حدد الخاصية بشكل صحيح كاعتمادية من التأثير.
- تجنب تحديثات الحالة في حالة إزالة المكون قبل انتهاء الطلب.
تتمثل إحدى الطرق البسيطة للإلغاء في استخدام علامة داخلية:
import { useEffect, useState } from "react";
import axios from "axios";
دالة المستخدم({ معرف المستخدم }) {
const [user, setUser] = useState(null);
استخدم التأثير(() => {
let isMounted = true;
const fetchData = async () => {
const result = await axios(
`https://jsonplaceholder.typicode.com/users/${userId}`
);
إذا (تم تركيبه) {
setUser(result.ata);
}
};
fetchData();
return () => {
isMounted = false;
};
}, [userId]);
إذا لم يكن هناك مستخدم {
يعود جارٍ الشحن… ;
}
إرجاع (
<div>
{اسم المستخدم}
عنوان البريد الإلكتروني: {user.email}
رقم الهاتف: {user.phone}
</div>
);
}
في حين البحر الجبلي trueيُسمح بتحديث الحالةعند إزالة المكون، يقوم تأثير التنظيف بتعيين تلك العلامة. falseوحتى لو تم الوفاء بالوعد لاحقاً، setUser لن يتم تنفيذه بعد الآن. توجد بدائل أكثر دقة (مثل وحدة التحكم في الإجهاض، ومكتبات البيانات، وما إلى ذلك)، لكن هذا النمط التوضيحي يوضح الفكرة بشكل جلي.
منطق إعادة الاستخدام: تأثيرات متعددة في نفس المكون
من أهم مزايا الخطافات أنها لا يقتصر استخدامك على تأثير استخدام واحد لكل مكونفي الواقع، عادةً ما يكون ذلك هو الأفضل. يمكن تقسيم المنطق إلى عدة تأثيرات متخصصة بدلاً من دمجها كلها في شيء واحد ضخم.
تخيل مكونًا يحتوي على كليهما محاسب, البيانات عن بعد و ربما اشتراكفي الفصل الدراسي، سينتهي بك الأمر إلى استخدام أساليب دورة الحياة المليئة بالرموز المختلطة: في componentDidMount لقد أطلقتَ العريضة ووقّعتَ عليها؛ في componentDidUpdate لقد تحققت يدويًا مما تغير؛ في componentWillUnmount لقد قمت بتنظيف كلا الشيئين.
باستخدام الخطافات، يمكنك استخدام تأثير استخدام واحد لكل "فكرة" أو مسؤولية:
import { useState, useEffect } from "react";
const MyComponent = () => {
const [count, setCount] = useState(0);
const [data, setData] = useState(null);
استخدم التأثير(() => {
console.log(«تم تثبيت المكون»);
}, []);
استخدم التأثير(() => {
console.log(`تم تغيير العدد إلى ${count}`);
}، [عدد])؛
استخدم التأثير(() => {
console.log("تم تغيير البيانات");
}، [بيانات])؛
إرجاع (
<div>
setCount((c) => c + 1)}>انقر هنا
</div>
);
};
وهكذا، لا يهتم كل تأثير إلا بما يثير اهتمامه.يصبح الكود أكثر وضوحًا، ويسهل إضافة أو إزالة سلوكيات معينة دون التأثير على باقي الكود. سيطبق React جميع تأثيرات المكونات بالترتيب الذي تُعلن عنه.
تحسين الأداء: تجنب تكرار التبعيات والتأثيرات بشكل مفرط.
عندما يقوم تأثير ما بعمل مكلف (استعلامات واجهة برمجة التطبيقات، وحسابات معقدة، وإعادة عرض من طرف ثالث...)، لا تريد تشغيله مع كل تحديث للمكون.في مكون الفئة، كان يتم حل هذه المشكلة غالبًا من خلال المقارنات اليدوية. if (prevProps.x !== this.props.x) ضمن componentDidUpdate.
مزودة بخطافات، تم دمج التحسين في توقيع useEffect نفسه. باستخدام مصفوفة التبعية. على سبيل المثال، إذا كنت تريد أن يتم تشغيل تأثير ما فقط عند تغييرها count، تُعلن ذلك على النحو التالي:
useEffect(() => {
console.log("Ha cambiado count");
}, [count]);
سيقوم React بمقارنة مصفوفة التبعيات القديمة [valorAnteriorDeCount] مع الجديد [valorNuevoDeCount]. إذا كانت جميع العناصر متطابقة، يتم تخطي التأثير.إذا كان هناك أي اختلاف، فسيتم تنظيف التأثير السابق (إذا كان هناك تنظيف) وسيتم تشغيل التكوين مرة أخرى.
وبالمثل، إذا كنت تريد تأثيرًا يعمل مرة واحدة فقط لتهيئة شيء ما (ويمكنك اختياريًا تنظيفه عند تفكيكه)، أنت تستخدم مصفوفة فارغةولكن كن حذرا: ستحتفظ الخصائص والحالة التي تقرأها داخل التأثير بقيمها الأولية.لذلك، ينبغي استخدام هذا النمط عندما تكون متأكدًا من أن تأثيرك لا يعتمد على أي تغيير.
ولتجنب أي سهو، يُنصح بشدة بتفعيل القاعدة exhaustive-deps de eslint-plugin-react-hooksتقوم هذه القاعدة بتحليل كود التأثير وتنبيهك في حال وجود أي تبعيات مفقودة، مع اقتراح الحل المناسب. إنها طريقة فعّالة للغاية لتجنب الأخطاء الدقيقة الناتجة عن استخدام قيم حالة أو خصائص قديمة.
المشاكل الشائعة المتعلقة بـ useEffect وكيفية تجنبها
يُعدّ التعامل مع المؤثرات بسيطًا من الناحية النظرية، ولكن من الناحية العملية، هناك عدد من التحديات. الأخطاء المتكررة وهذا شيء يجب أن نضعه في الاعتبار دائماً حتى لا نقع في هذه الأخطاء مراراً وتكراراً.
أحد أكثر المواضيع التي يتم الحديث عنها هو حلقة عرض لا نهائيةيحدث ذلك عندما يكون تأثيرك يقوم بتحديث حالة تُعد جزءًا من تبعياته بطريقة لا تؤدي إلى التقارب. على سبيل المثال، إذا كان لديك:
useEffect(() => {
setCount(count + 1);
}, [count]);
في كل عملية عرض، كما count يتغير، ثم يُعاد تشغيل التأثير، وتقوم بتحديث الحالة مرة أخرى، وهكذا إلى ما لا نهاية. في هذه الحالات، إما أنك في المكان الخطأ (لا ينبغي أن يكون هذا التحديث ضمن تأثير)، أو أنك بحاجة إلى أنواع أخرى من المنطق، مثل الفاصل الزمني مع التنظيفأو استخدم الصيغة الوظيفية setCount(c => c + 1) بدون وضع count في المبنى.
وثمة مشكلة أخرى تتمثل في الشعور بأن التأثير "يتم تشغيله مرتين عند التركيب"في الوضع الصارم، يُجري React في بيئة التطوير نوعًا من "اختبار التحمل" عن طريق تشغيل عملية الإعداد ← التنظيف ← الإعداد مرة أخرى في البداية. هذا لا يحدث في بيئة الإنتاج، ولكن إنه يسلط الضوء على المؤثرات المصممة بشكل سيئ والتي لا تنظف بشكل صحيح.إذا كانت منطق التنظيف لديك متناظرة مع منطق الإعداد لديك، فلن يلاحظ المستخدم أي شيء غير عادي.
من الشائع أيضاً رؤية تأثيرات تتكرر في كل عملية عرض على الرغم من وجود تبعيات بينها. يحدث هذا عادةً لأن تتضمن المصفوفة كائنات أو دوال تم إنشاؤها في كل عملية عرضبما أن المراجع تتغير باستمرار، يفترض React أن التبعية قد تغيرت أيضًا. الحل: قم بتعريف تلك الوظائف أو الكائنات داخل التأثير نفسه أو احفظها باستخدام useCallback/useMemo إذا كانت هناك حاجة ماسة إليها في الخارج.
استخدام التأثير، والأنظمة الخارجية، والاستخدام المتقدم مع أحداث التأثير
سبب كونه من استخدام التأثير es حافظ على مزامنة مكونك مع الأنظمة الخارجية: المقابس، والخرائط، ومشغلات الفيديو المضمنة، وواجهات برمجة تطبيقات المتصفح، وما إلى ذلك. يعتمد النمط دائمًا على فكرة "عندما تتغير هذه التبعيات، أعد الاتصال بالقيم الجديدة وانفصل عن القيم القديمة".
على سبيل المثال، أحد المكونات ChatRoom والتي تتصل بغرفة معينة حسب serverUrl y roomId ينبغي:
- اتصل أثناء الركوب باستخدام أول مجموعة من
serverUrlyroomId. - قم بفصل الاتصال بالغرفة السابقة والاتصال بالغرفة الجديدة إذا قام المستخدم بتغيير الغرف أو الخوادم.
- افصل الجهاز تماماً عند تفكيك المكون.
باستخدام useEffect وعملية تنظيف جيدة، يمكنك تحقيق ذلك. لكل عملية عرض ترابطها المتماسك وأن React يمكنها تكرار تسلسل الإعداد/التنظيف دون ترك أي شيء معلقًا.
في سيناريوهات أكثر تعقيدًا، قد تحتاج اقرأ أحدث حالة وخصائص داخل التأثير دون التسبب في إعادة تنفيذه.وهنا تبرز أهمية أنماط كهذه. أحداث التأثير (مثل الخطافات) useEffectEvent في التوصيات الجديدة)، والتي تسمح لك بنقل بعض التعليمات البرمجية غير التفاعلية من قائمة التبعيات. وفي الوقت نفسه، يتمثل النهج العملي في استخدم مراجع أو خطافات مخصصة بالنسبة لتلك القطع التي لا يتناسب معها السلوك التفاعلي الكلاسيكي بشكل جيد.
في سياق عرض المحتوى من جانب الخادم (SSR)، ضع في اعتبارك ما يلي: لا تعمل التأثيرات إلا على جهاز العميليتم عرض كود HTML الأولي على الخادم، وبمجرد تحميل التطبيق في المتصفح، يتم استدعاء عبارات useEffect. إذا كنت ترغب في عرض شيء مختلف على جانب العميل فقط، يمكنك استخدام حالة مثل didMount هذا يمر false a true في تأثير مع [] ثم قم بتكييف العرض من هناك.
للسيطرة استخدام y استخدام التأثير في النهاية، يكمن الأمر في استيعاب أن كل عملية عرض هي لقطة لمكونك، وأن الخطافات مرتبطة بترتيب تعريفها، وأن التأثيرات تصف كيفية مزامنة هذه اللقطة مع العالم الخارجي، بما في ذلك كيفية التراجع عما يجب التراجع عنه. مع إدارة جيدة للتبعيات، وتنظيفها، وفصل التأثيرات حسب مسؤولياتها، ستعمل مكوناتك بشكل أكثر قابلية للتنبؤ، وتستهلك موارد أقل، وسيكون من الأسهل بكثير تحديد سبب المشكلة عندما لا يتصرف شيء ما كما ينبغي.