العودة للمقالات

ما وراء useEffect: إتقان نظام التأثيرات في React

المؤلفMajd Muhtaseb03‏/08‏/20258 دقيقة
ما وراء useEffect: إتقان نظام التأثيرات في React

مقدمة

تعتبر useEffect حجر الزاوية في تطوير React، مما يتيح إجراء تأثيرات جانبية داخل المكونات الوظيفية. على الرغم من بساطتها الظاهرة، فإن إتقان useEffect يتطلب فهم التبعيات والمزالق المحتملة. تتعمق هذه المقالة في استكشاف التقنيات المتقدمة وأفضل الممارسات لاستخدام useEffect بفعالية.

مصفوفة التبعية: مفتاحك للتحكم

مصفوفة التبعية أمر بالغ الأهمية. فهي تحدد متى يتم إعادة تنفيذ وظيفة التأثير. يؤدي حذفها تمامًا إلى تشغيل التأثير بعد كل عملية عرض، وهو أمر غير مرغوب فيه غالبًا ويمكن أن يؤدي إلى مشاكل في الأداء أو حلقات لا نهائية.

import React, { useState, useEffect } from 'react';

function MyComponent() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    console.log('يتم تشغيل التأثير!');
    document.title = `العدد: ${count}`;
  }, [count]); // التأثير يعمل فقط عندما يتغير 'count'

  return (
    <div>
      <p>العدد: {count}</p>
      <button onClick={() => setCount(count + 1)}>زيادة</button>
    </div>
  );
}

export default MyComponent;

في هذا المثال، يعمل التأثير فقط عندما يتغير count. بدون مصفوفة التبعية، سيتم تحديث document.title بعد كل عملية عرض، حتى لو ظل count كما هو.

مصفوفة التبعية الفارغة: useEffect عند التحميل

يؤدي استخدام مصفوفة تبعية فارغة ([]) إلى تشغيل التأثير مرة واحدة فقط، على غرار componentDidMount في مكونات الفئة.

import React, { useEffect } from 'react';

function MyComponent() {
  useEffect(() => {
    console.log('تم تحميل المكون!');
    // جلب البيانات الأولية هنا
  }, []); // التأثير يعمل مرة واحدة فقط عند التحميل

  return (
    <div>
      <p>مرحبا بالعالم!</p>
    </div>
  );
}

export default MyComponent;

وظائف التنظيف: منع تسرب الذاكرة

يمكن لـ useEffect إرجاع وظيفة تنظيف، والتي يتم تنفيذها عند إلغاء تحميل المكون أو قبل إعادة تشغيل التأثير (إذا تغيرت التبعيات). هذا ضروري لمنع تسرب الذاكرة، خاصة عند التعامل مع المؤقتات أو الاشتراكات أو مستمعي الأحداث.

import React, { useState, useEffect } from 'react';

function MyComponent() {
  const [width, setWidth] = useState(window.innerWidth);

  useEffect(() => {
    const handleResize = () => setWidth(window.innerWidth);
    window.addEventListener('resize', handleResize);

    return () => {
      console.log('تنظيف مستمع الحدث');
      window.removeEventListener('resize', handleResize);
    };
  }, []); // التأثير يعمل مرة واحدة فقط عند التحميل ويتم تنظيفه عند إلغاء التحميل

  return (
    <div>
      <p>عرض النافذة: {width}</p>
    </div>
  );
}

export default MyComponent;

تضمن وظيفة التنظيف إزالة مستمع حدث resize عند إلغاء تحميل المكون، مما يمنع تسرب الذاكرة المحتمل.

useCallback و useMemo: تحسين التبعيات

عند استخدام الدوال أو الكائنات كتبعيات، يمكن لـ useCallback و useMemo منع إعادة عرض التأثير غير الضرورية. بدونها، يتم إنشاء دالة أو مثيل كائن جديد في كل عملية عرض، مما يتسبب في إعادة تشغيل التأثير حتى إذا لم يتغير المنطق الأساسي.

import React, { useState, useEffect, useCallback } from 'react';

function MyComponent() {
  const [count, setCount] = useState(0);

  const handleClick = useCallback(() => {
    setCount(prevCount => prevCount + 1);
  }, []);

  useEffect(() => {
    console.log('تغير handleClick، لذلك يعمل هذا التأثير');
  }, [handleClick]);

  return (
    <div>
      <p>العدد: {count}</p>
      <button onClick={handleClick}>زيادة</button>
    </div>
  );
}

export default MyComponent;

يقوم useCallback بحفظ handleClick في الذاكرة مؤقتًا، مما يضمن أنه يتغير فقط عندما تتغير تبعياته الخاصة (في هذه الحالة، لا شيء). هذا يمنع useEffect من إعادة التشغيل دون داع.

خاتمة

يعد إتقان useEffect أمرًا بالغ الأهمية لبناء تطبيقات React عالية الأداء وقابلة للصيانة. من خلال فهم مصفوفة التبعية ووظائف التنظيف وتقنيات التحسين مثل useCallback و useMemo، يمكنك إطلاق الإمكانات الكاملة لنظام تأثيرات React وتجنب المزالق الشائعة. تذكر دائمًا أن تدرس تبعياتك بعناية وتضمن التنظيف المناسب لمنع تسرب الذاكرة.