فهرست سرفصل‌های React
خانه (Home) مقدمه (Intro) شروع کار (Get Started) اولین اپ (First App) رندر HTML (Render HTML) ارتقا (Upgrade) آشنایی با ES6 (ES6) کلاس ها در ES6 (ES6 Classes) توابع پیکانی ES6 (ES6 Arrow Functions) متغیرها در ES6 (ES6 Variables) متد map روی آرایه ها (ES6 Array map()) دیس ترکچرینگ (تقسیم ساختاری) (ES6 Destructuring) عملگر پخش (Spread) (ES6 Spread Operator) ماژول ها در ES6 (ES6 Modules) عملگر سه تایی (Ternary) (ES6 Ternary Operator) رشته های قالبی (Template Strings) (ES6 Template Strings) مقدمه JSX (JSX Intro) عبارت ها در JSX (JSX Expressions) خصیصه ها در JSX (JSX Attributes) شرط ها در JSX (JSX If Statements) کامپوننت ها (Components) کلاس ها (Class) پراپس ها (Props) (Props) دیس ترکچرینگ پراپس ها (Props Destructuring) پراپس children (Props Children) رویدادها (Events) رندر شرطی (Conditionals) لیست ها (Lists) فرم ها (Forms) ارسال فرم (Forms Submit) فیلد Textarea (Textarea) فیلد Select (Select) چند ورودی در فرم (Multiple Inputs) چک باکس (Checkbox) دکمه های رادیویی (Radio) پورتال ها (Portals) Suspense (Suspense) استایل دهی با CSS (CSS Styling) CSS Modules (CSS Modules) CSS-in-JS (CSS-in-JS) مسیریابی (Router) (Router) ترنزیشن ها (Transitions) (Transitions) Forward Ref (Forward Ref) کامپوننت های مرتبه بالاتر (HOC) (HOC) استایل دهی با Sass (Sass) هوکس چیست؟ (What is Hooks?) هوک useState (useState) هوک useEffect (useEffect) هوک useContext (useContext) هوک useRef (useRef) هوک useReducer (useReducer) هوک useCallback (useCallback) هوک useMemo (useMemo) هوک های سفارشی (Custom Hooks) کامپایلر (Compiler) کوئیز (آزمون کوتاه) (Quiz) تمرین ها (Exercises) سیلابس (سرفصل دوره) (Syllabus) برنامه مطالعه (Study Plan) سرور (Server) آمادگی مصاحبه (Interview Prep) گواهینامه (Certificate)
نتیجه‌ای برای جستجو یافت نشد.
React

React — هوک useEffect (useEffect)

آخرین بروزرسانی: 1404/08/24

هوک useEffect (useEffect)

هوک useEffect در ری اکت کمک می کند کارهای جانبی یا ساید افکت (Side Effect) را انجام بدهی. مثلا گرفتن داده از سرور، تغییر مستقیم DOM، یا ساختن تایمر. با useEffect در ری اکت می توانی بگویی «این کار را بعد از هر رندر، یا فقط بعضی وقت ها انجام بده».

هوک useEffect در ری اکت چیست؟

ساید افکت یعنی کاری خارج از نمایش ساده UI. مثلا درخواست به سرور، تایمر، یا گوش دادن به رویدادهای صفحه.

هوک useEffect در ری اکت تابعی است که به شکل useEffect(fn, deps) صدا زده می شود. آرگومان اول یک تابع است؛ آرگومان دوم یک آرایه وابستگی است و اختیاری است.

اگر آرایه وابستگی را درست تنظیم کنی، دقیقا کنترل می کنی useEffect در ری اکت چه زمانی اجرا شود.

مثال تایمر با useEffect در ری اکت

بیایید از یک تایمر ساده شروع کنیم. در این مثال، هر ثانیه مقدار count یک واحد بیشتر می شود.

import { useState, useEffect } from "react";
import { createRoot } from "react-dom/client";

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

  useEffect(() => {
    setTimeout(() => {
      setCount((count) => {
        return count + 1;
      });
    }, 1000);
  });

  return (
    <h1>
      I've rendered {count} times!
    </h1>
  );
}

createRoot(document.getElementById("root")).render(
  <Timer />
);

مشاهده در ادیتور

اینجا useEffect در ری اکت بعد از هر رندر اجرا می شود. چون setCount صدا می زنیم، دوباره رندر می گیرد و باز useEffect اجرا می شود. نتیجه این است که شمارنده مدام بالا می رود، نه فقط یک بار.

آرایه وابستگی useEffect در ری اکت

برای کنترل زمان اجرا، آرگومان دوم useEffect را تنظیم می کنیم. این آرگومان یک آرایه است که به آن آرایه وابستگی (Dependency Array) می گوییم.

اگر چیزی در این آرایه نباشد، یا آرایه خالی، یا مقادیر state و props باشد، رفتار useEffect عوض می شود.

1. بدون آرایه وابستگی

اگر آرگومان دوم را ندهی، useEffect در هر رندر اجرا می شود.

useEffect(() => {
  // Runs on every render
});

مشاهده در ادیتور

2. آرایه خالی به عنوان وابستگی

اگر آرایه خالی بدهی، useEffect فقط یک بار اجرا می شود؛ دقیقا بعد از رندر اول.

useEffect(() => {
  // Runs only on the first render
}, []);

مشاهده در ادیتور

3. وابسته به props یا state

اگر state یا props داخل آرایه باشند، useEffect در ری اکت روی آن ها واکنش می دهد.

useEffect(() => {
  // Runs on the first render
  // And any time any dependency value changes
}, [prop, state]);

مشاهده در ادیتور

گام های تمرین با useEffect

  1. یک کامپوننت Timer ساده بساز.
  2. داخل آن state با نام count تعریف کن.
  3. useEffect را بدون آرایه وابستگی بنویس و رفتار را ببین.
  4. سپس آرایه خالی قرار بده و نتیجه را مقایسه کن.
  5. در نهایت count را در آرایه وابستگی بگذار و رفتار را بررسی کن.

اصلاح تایمر با آرایه وابستگی خالی

برای این که تایمر فقط یک بار اجرا شود، کافی است آرایه وابستگی خالی بدهیم. این یعنی «فقط بعد از اولین رندر اجرا شو».

import { useState, useEffect } from "react";
import { createRoot } from "react-dom/client";

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

  useEffect(() => {
    setTimeout(() => {
      setCount((count) => {
        return count + 1;
      });
    }, 1000);
  }, []);

  return (
    <h1>
      I've rendered {count} times!
    </h1>
  );
}

createRoot(document.getElementById("root")).render(
  <Timer />
);

مشاهده در ادیتور

حالا تایمر فقط یک بار بعد از رندر اول اجرا می شود. count یک بار زیاد می شود و تمام.

مثال useEffect وابسته به state

گاهی می خواهی هر وقت یک state عوض شد، چیزی دوباره محاسبه شود. مثلا یک مقدار محاسباتی بر اساس count.

import { useState, useEffect } from "react";
import { createRoot } from "react-dom/client";

function Counter() {
  const [count, setCount] = useState(0);
  const [calculation, setCalculation] = useState(0);

  useEffect(() => {
    setCalculation(() => {
      return count * 2;
    });
  }, [count]);

  return (
    <>
      <p>
        Count: {count}
      </p>
      <button
        onClick={() => {
          setCount((c) => {
            return c + 1;
          });
        }}
      >
        +
      </button>
      <p>
        Calculation: {calculation}
      </p>
    </>
  );
}

createRoot(document.getElementById("root")).render(
  <Counter />
);

مشاهده در ادیتور

اینجا useEffect در ری اکت وقتی اجرا می شود که count تغییر کند. در هر کلیک، count زیاد می شود و calculation دوباره حساب می شود.

نکته: اگر چند وابستگی داری، همه را داخل آرایه وابستگی useEffect بنویس.

پاک سازی اثرها در useEffect (Effect Cleanup)

بعضی افکت ها باید بعدا تمیز شوند. مثلا تایمرها، event listenerها و اشتراک ها. اگر تمیز نشوند، ممکن است حافظه اضافی مصرف کنند.

برای پاک سازی، از داخل useEffect یک تابع برگردان. این تابع هنگام حذف کامپوننت یا تغییر وابستگی ها اجرا می شود.

import { useState, useEffect } from "react";
import { createRoot } from "react-dom/client";

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

  useEffect(() => {
    const timer = setTimeout(() => {
      setCount((count) => {
        return count + 1;
      });
    }, 1000);

    return () => {
      clearTimeout(timer);
    };
  }, []);

  return (
    <h1>
      I've rendered {count} times!
    </h1>
  );
}

createRoot(document.getElementById("root")).render(
  <Timer />
);

مشاهده در ادیتور

برای این که بتوانیم تایمر را پاک کنیم، آن را در متغیر timer نگه داشتیم. بعد در تابع برگشتی clearTimeout را صدا زدیم.

اگر هنوز با state راحت نیستی، پیشنهاد می کنم اول صفحه هوک useState در ری اکت را خوب بخوانی. بعد دوباره سراغ این صفحه برگرد.

همچنین برای دیدن تصویر کامل تر، صفحه هوکس در ری اکت را هم ببین تا بدانی useEffect در کنار بقیه هوک ها کجا قرار می گیرد.

جمع بندی سریع

  • هوک useEffect در ری اکت برای انجام ساید افکت ها استفاده می شود.
  • آرگومان دوم useEffect در ری اکت زمان اجرای افکت را کنترل می کند.
  • آرایه خالی یعنی فقط بعد از رندر اول اجرا شو.
  • قرار دادن state در آرایه یعنی بعد از هر تغییر آن state اجرا شو.
  • برای تایمر و لیسنرها، همیشه تابع پاک سازی داخل useEffect بنویس.