Effect چیست و نقش Dependency Array

در فصل پنجم به‌طور مختصر با useEffect آشنا شدیم. از این فصل به بعد، به‌طور کامل و با جزئیات به سراغ Effectها می‌رویم؛ مفهومی که یکی از پرکاربردترین و در عین حال پراشتباه‌ترین بخش‌های React برای تازه‌کارهاست.

Effect چیست

یک Effect، بخشی از کد است که کامپوننت را با چیزی خارج از خود React همگام (Synchronize) می‌کند؛ مواردی مانند تنظیم عنوان صفحه، اتصال به یک سرویس خارجی، تنظیم یک تایمر، یا ارسال درخواست به سرور. تفاوت اصلی Effect با بقیه کدهای داخل یک کامپوننت این است که Effect پس از رندر و اعمال تغییرات در DOM اجرا می‌شود، نه در حین محاسبه خروجی JSX.

import { useEffect } from "react";

function PageTitle({ title }) {
  useEffect(() => {
    document.title = title;
  });

  return <h2>{title}</h2>;
}

در این مثال، تغییر عنوان تب مرورگر کاری است که خارج از React انجام می‌شود (روی آبجکت document)؛ به همین دلیل باید داخل یک Effect نوشته شود، نه مستقیماً در بدنه اصلی کامپوننت.

بدون Dependency Array: اجرا پس از هر رندر

اگر به useEffect فقط یک تابع بدهیم، بدون آرگومان دوم، آن Effect پس از هر رندر کامپوننت، بدون استثنا، دوباره اجرا می‌شود. این رفتار در بسیاری از موارد لازم نیست و می‌تواند باعث اجرای غیرضروری Effect شود.

Dependency Array: کنترل زمان اجرای Effect

آرگومان دوم useEffect، آرایه‌ای است به نام Dependency Array که مشخص می‌کند Effect باید به تغییر کدام مقادیر واکنش نشان دهد. React مقادیر این آرایه را بین رندر فعلی و رندر قبلی مقایسه می‌کند؛ اگر حداقل یکی از آن‌ها تغییر کرده باشد، Effect دوباره اجرا می‌شود.

useEffect(() => {
  document.title = title;
}, [title]);

در این نسخه، Effect فقط زمانی دوباره اجرا می‌شود که مقدار title نسبت به رندر قبلی تغییر کرده باشد؛ نه با هر رندر کامپوننت، حتی اگر آن رندر به دلیل تغییر مقداری دیگر رخ داده باشد.

آرایه خالی: اجرا فقط یک‌بار

اگر Dependency Array یک آرایه خالی باشد، به این معناست که هیچ مقداری وجود ندارد که با تغییرش، Effect باید دوباره اجرا شود؛ در نتیجه، این Effect فقط یک‌بار، پس از اولین رندر کامپوننت، اجرا می‌شود:

useEffect(() => {
  console.log("این کامپوننت برای اولین بار نمایش داده شد");
}, []);

سه حالت اصلی Dependency Array

به‌طور خلاصه، سه حالت اصلی برای آرگومان دوم useEffect وجود دارد:

  • بدون آرگومان دوم: اجرا پس از هر رندر.
  • آرایه خالی []: اجرا فقط یک‌بار، پس از اولین رندر.
  • آرایه با یک یا چند مقدار: اجرا پس از اولین رندر، و سپس فقط زمانی که یکی از آن مقادیر تغییر کند.

یک اصل مهم: هر مقدار خوانده‌شده داخل Effect باید در آرایه باشد

یک قاعده مهم که در درس‌های بعدی این فصل با جزئیات بیشتری بررسی می‌شود، این است که هر متغیری از بدنه کامپوننت (مانند Props یا State) که داخل Effect خوانده می‌شود، معمولاً باید در Dependency Array هم ذکر شود. نادیده گرفتن این اصل، یکی از منابع اصلی اشکالات ظریف در برنامه‌های React است که در درس‌های آینده همین فصل بررسی خواهیم کرد.

مثال قابل اجرا

مقایسه Effect با و بدون Dependency Array
برای دیدن پیش‌نمایش کامپوننت، روی Run بزنید.

جمع‌بندی

Effect بخشی از کامپوننت است که پس از رندر اجرا می‌شود و کامپوننت را با چیزی خارج از React همگام می‌کند. Dependency Array مشخص می‌کند این همگام‌سازی باید به تغییر کدام مقادیر واکنش نشان دهد: بدون آن، Effect بعد از هر رندر اجرا می‌شود؛ با آرایه خالی، فقط یک‌بار؛ و با مقادیر مشخص، فقط وقتی آن مقادیر تغییر کنند. در درس بعدی به مفهوم Cleanup در Effectها می‌پردازیم.