Kodokon kodokon.com

useEffect: التأثيرات والتبعيات والتنظيف

زامِن مكوّناتك مع العالم الخارجي باستخدام useEffect، مع إتقان التبعيات والتنظيف.

9 دقيقة · 3 أسئلة

افتح هذا الدرس في Kodokon

يحسب مكوّن React الـ JSX انطلاقاً من الـ props والحالة. أي شيء خارج هذا النطاق - تغيير عنوان المستند، بدء مؤقّت، الاشتراك في حدث متصفح - هو تأثير جانبي. يشغّل useEffect تلك الشيفرة بعد العرض، دون حجب العرض المرئي، ويعيد مزامنتها عندما تتغير قيم معينة.

JSX
import { useEffect } from "react";

function CartTitle({ count }) {
  useEffect(() => {
    document.title = `Cart (${count})`;
  }, [count]);

  return <p>Items: {count}</p>;
}
لا يُعاد تشغيل التأثير إلا عندما تتغير count.

يتحكم مصفوف التبعيات في عدد مرات تشغيل التأثير. [count]: يُعاد تشغيل التأثير بعد كل عرض تغيرت فيه count. []: يُشغّل التأثير مرة واحدة فقط، بعد العرض الأول. بلا مصفوف: يُعاد تشغيل التأثير بعد كل عرض، وهذا نادراً ما تريده. القاعدة الذهبية: كل قيمة من قيم المكوّن تُستخدم داخل التأثير يجب أن تظهر في المصفوف.

JSX
import { useEffect, useState } from "react";

function Timer() {
  const [seconds, setSeconds] = useState(0);

  useEffect(() => {
    const id = setInterval(() => {
      setSeconds((s) => s + 1);
    }, 1000);

    return () => clearInterval(id);
  }, []);

  return <p>Elapsed: {seconds} s</p>;
}
بدون clearInterval، كان المؤقّت سيتجاوز عمر المكوّن.

الدالة التي يعيدها التأثير هي دالة التنظيف. تستدعيها React قبل كل تشغيل جديد للتأثير، ثم مرة أخيرة عند فك تركيب المكوّن. هي ما يمنع التسريبات: المؤقّتات اليتيمة، والمستمِعون المتراكمون، والاشتراكات التي لا تُلغى أبداً. كل تأثير “يفتح” شيئاً يجب أن يغلقه من جديد.

JSX
useEffect(() => {
  function onResize() {
    setWidth(window.innerWidth);
  }
  window.addEventListener("resize", onResize);

  return () => {
    window.removeEventListener("resize", onResize);
  };
}, []);
الاشتراك في حدث resize، مع إلغائه عند فك التركيب.

اختبار المعرفة

تأكّد من أنك تذكّرت النقاط الأساسية في هذا الدرس.

  1. مع useEffect(fn, [])، متى تُنفَّذ الدالة fn؟
    • قبل كل عرض للمكوّن
    • بعد العرض الأول فقط
    • عند كل تحديث للحالة
  2. متى تُستدعى دالة التنظيف التي يعيدها التأثير؟
    • فقط عند فك تركيب المكوّن
    • قبل كل إعادة تشغيل للتأثير وعند فك التركيب
    • قبل العرض الأول للمكوّن مباشرة
    • أبداً بشكل تلقائي: عليك استدعاؤها بنفسك
  3. يقرأ تأثير القيمة userId لكن مصفوف تبعياته هو []. ما المشكلة؟
    • لن يُعاد تشغيل التأثير عند تغيّر userId وسيحتفظ بقيمة قديمة
    • ستطلق React خطأً عند العرض الأول
    • سيُعاد تشغيل التأثير في حلقة لا نهائية