🚀 احتراف useEffect: كيف تتحكم في "الآثار الجانبية" في React؟
بعد أن تعلمت كيف تدير الحالة (State) باستخدام useState في الدروس السابقة، حان الوقت لنتعلم واحدة من أهم الأدوات في React، وهي الـ Hook المسمى useEffect.
هل تساءلت يوماً: كيف أجعل الكود يعمل "تلقائياً" بمجرد ظهور الصفحة؟ أو كيف أقوم بتحديث عنوان الصفحة عندما يتغير اسم المستخدم؟ هنا يأتي دور useEffect.
❓ ما هو الـ useEffect ولماذا نحتاجه؟ 🤔
في React، معظم المكونات (Components) تقوم فقط بعرض البيانات (UI). ولكن في الواقع، نحتاج أحياناً للقيام بعمليات "خارج" نطاق العرض، وهذه العمليات نسميها Side Effects (آثار جانبية).
أمثلة على الآثار الجانبية (Side Effects):
- جلب بيانات من خادم (API) عند فتح الصفحة.
- تغيير عنوان الصفحة (Document Title) في المتصفح.
- تشغيل مؤقت زمني (Timer) أو عداد.
- التفاعل مع مكتبات خارجية لا تتبع نظام React.
الـ useEffect هو الـ Hook الذي يخبر React: "من فضلك، بعد أن تنتهي من رسم المكون على الشاشة، قم بتنفيذ هذا الكود".
🛠️ التركيبة الأساسية لـ useEffect
لكي نستخدم useEffect في مشروعنا، يجب أولاً استيراده من مكتبة React:
import { useEffect } from 'react';
الشكل العام لكتابة الـ Hook:
useEffect(() => {
// هنا نكتب الكود الذي نريد تنفيذه (الآثار الجانبية)
}, [dependencies]); // مصفوفة الاعتمادات
تتكون useEffect من جزئين أساسيين:
- الدالة (Function): وهي التي تحتوي على الكود الذي سيتم تنفيذه.
- مصفوفة الاعتمادات (Dependency Array): وهي المربع
[]الموجود في النهاية، وهو الذي يحدد متى يعمل الكود.
🚦 حالات تشغيل useEffect (مهم جداً!)
هنا يقع معظم المبتدئين في حيرة، لكن الأمر بسيط جداً. هناك 3 سيناريوهات لتشغيل useEffect:
1. التنفيذ عند كل عملية ريندر (بدون مصفوفة) 🔄
إذا لم تضع مصفوفة الاعتمادات في النهاية، سيعمل الكود في كل مرة يتم فيها تحديث المكون. (لا ينصح بهذا غالباً لأنه قد يبطئ التطبيق).
useEffect(() => {
console.log("I run on every render!");
}); // لاحظ عدم وجود [ ] هنا
2. التنفيذ لمرة واحدة فقط (مصفوفة فارغة []) 🕒
إذا وضعت مصفوفة فارغة، سيعمل الكود مرة واحدة فقط عند ظهور المكون لأول مرة على الشاشة (Mounting). هذا هو الوضع الأكثر استخداماً (مثلاً لجلب بيانات من API).
useEffect(() => {
console.log("I run only once when the component mounts!");
}, []); // مصفوفة فارغة
3. التنفيذ عند تغيير قيمة معينة (مصفوفة بها متغيرات) 🎯
إذا وضعت متغيراً داخل المصفوفة، سيعمل الكود في المرة الأولى، ثم في كل مرة تتغير فيها قيمة هذا المتغير.
useEffect(() => {
console.log("The count has changed!");
}, [count]); // سيعمل الكود فقط عندما تتغير قيمة count
💻 مثال عملي: تغيير عنوان الصفحة بناءً على عداد
لنطبق ما تعلمناه في مثال بسيط. سنقوم بإنشاء عداد، وفي كل مرة يضغط المستخدم على الزر، سنقوم بتحديث عنوان المتصفح (Title) ليعرض الرقم الحالي.
import React, { useState, useEffect } from 'react';
function CounterApp() {
const [count, setCount] = useState(0);
// useEffect لتحديث عنوان الصفحة في المتصفح
useEffect(() => {
document.title = `Count is ${count}`; // تحديث العنوان
console.log("Updating document title..."); // تعليق لمتابعة التنفيذ في الـ Console
}, [count]); // الكود سيعمل فقط عندما تتغير قيمة count
return (
<div style={{ textAlign: 'center', marginTop: '50px' }}>
<h1>React useEffect Demo</h1>
<p>Current Count: {count}</p>
<button onClick={() => setCount(count + 1)}>
Increase Count
</button>
</div>
);
}
export default CounterApp;
شرح ما حدث في الكود:
- قمنا بتعريف حالة
countلتبدأ من 0. - استخدمنا
useEffectومررنا لها[count]في مصفوفة الاعتمادات. - عندما يضغط المستخدم على الزر تزداد قيمة
countيشعر React بالتغيير يقوم بتنفيذ الكود الموجود داخلuseEffectيتغير عنوان الصفحة.
⚠️ ملاحظة أخيرة للمبتدئين
تذكر دائماً أن useEffect تعمل بعد أن يتم عرض المكون على الشاشة. هذا يعني أن المستخدم سيرى الواجهة أولاً، ثم يتم تنفيذ العمليات الجانبية. هذا يضمن أن التطبيق يظل سريعاً وسلساً.
⏭️ ماذا سنتعلم في الدرس القادم؟
الآن بعد أن عرفنا كيف نقوم بتنفيذ أكواد عند ظهور المكون أو تحديثه، ماذا لو أردنا "تنظيف" هذه العمليات قبل أن يختفي المكون من الشاشة؟ (مثل إيقاف مؤقت أو إلغاء اشتراك).
في الدرس القادم، سنتعرف على مفهوم "useEffect Cleanup Function" وكيف نمنع حدوث تسريب في الذاكرة (Memory Leaks) في تطبيقاتنا. نراك هناك! 👋
🎓 اختبر معلوماتك
التعليقات
شاركنا رأيك أو أسئلتك حول هذا المقال