ویرگول
ورودثبت نام
مهدی فرجی
مهدی فرجی
مهدی فرجی
مهدی فرجی
خواندن ۳ دقیقه·۲ روز پیش

راهنمای useEffect و Cleanup توی React

React useEffect hook cleanup
React useEffect hook cleanup

ببین وقتی توی React از useEffect استفاده میکنیم، معمولاً داریم یه کار جانبی انجام میدیم. مثلا:

  • تایمر میذاریم

  • به یه event گوش میدیم

  • درخواست API میزنیم

  • WebSocket باز میکنیم

  • subscription میسازیم

حالا نکته مهم چیه؟
اینه که وقتی کامپوننت از بین میره (Unmount میشه) یا دوباره قراره effect اجرا بشه، باید اون چیزایی که ساختیم رو پاک کنیم.

اگه پاکشون نکنیم چی میشه؟

  • اپ کند میشه

  • memory leak میخوریم

  • ارورهای عجیب میاد

  • state روی کامپوننتی که دیگه وجود نداره ست میشه

اصلاً Cleanup یا همون پاک کردن چیه؟

ساختار useEffect اینجوریه:

useEffect(() => { // کار اصلی اینجاست return () => { // این قسمت همون cleanup هست }; }, []);

اون تابعی که داخل return برمیگردونی، همون تمیزکاریه. React هر وقت بخواد effect رو ببنده یا دوباره اجرا کنه، اول cleanup قبلی رو صدا میزنه.

تایمر گذاشتی؟

useEffect(() => { const interval = setInterval(() => { console.log("hello"); }, 2000); return () => clearInterval(interval); }, []);

اگه clearInterval نزنی، حتی بعد از اینکه از صفحه رفتی بیرون، تایمر همچنان اجرا میشه.

بعد میگی چرا لاگ هنوز میاد؟ چرا باتری خالی میشه؟ چرا اپ کند شده؟

هر setInterval یا setTimeout = حتماً clear کن

Event Listener ساختی؟

توی React خیلی وقتا به event ها گوش میدیم. مثلا کیبورد:

useEffect(() => { const showSub = Keyboard.addListener("keyboardDidShow", () => {}); const hideSub = Keyboard.addListener("keyboardDidHide", () => {}); return () => { showSub.remove(); hideSub.remove(); }; }, []);

اگه remove نکنی، بعداً هم اجرا میشه حتی وقتی اون صفحه دیگه وجود نداره. این باعث رفتارهای غیرقابل پیشبینی میشه. هر addListener = یه remove لازم داره.

درخواست API زدی؟

فرض کن اینو نوشتی:

useEffect(() => { fetch("https://example.com") .then(res => res.json()) .then(data => setData(data)); }, []);

حالا کاربر سریع از صفحه میره بیرون ولی درخواست هنوز در حال انجامه. وقتی جواب بیاد، میخواد setData بزنه روی کامپوننتی که دیگه وجود نداره.

اینجاست که ارور معروف میاد:

Can't perform a React state update on an unmounted component

راه حل چیه؟ AbortController

useEffect(() => { const controller = new AbortController(); fetch("https://example.com", { signal: controller.signal }) .then(res => res.json()) .then(data => setData(data)) .catch(err => { if (err.name !== "AbortError") { console.error(err); } }); return () => controller.abort(); }, []);

اینجوری وقتی صفحه بسته بشه، درخواست هم لغو میشه.

WebSocket باز کردی؟

اگه WebSocket باز کنی و نبندیش، اتصال همچنان باز میمونه و دیتا رد و بدل میشه.

useEffect(() => { const ws = new WebSocket("wss://example.com"); ws.onmessage = (event) => { console.log(event.data); }; return () => { ws.close(); }; }, []);

خیلی از باگهای اپهای realtime از همینجا میاد.

هر اتصال = یه close لازم داره

چند تا cleanup داری؟

بعضی وقتا cleanup شلوغ میشه:

return () => { sub1.remove(); sub2.remove(); clearInterval(timer); };

میتونی تمیزترش کنی:

useEffect(() => { const cleanups = []; const sub = something(); cleanups.push(() => sub.remove()); const timer = setInterval(() => {}, 1000); cleanups.push(() => clearInterval(timer)); return () => { cleanups.forEach(fn => fn()); }; }, []);

Cleanup کی اجرا میشه؟

دو حالت داره:

۱. وقتی کامپوننت Unmount میشه

۲. وقتی dependencyها تغییر میکنن و effect قراره دوباره اجرا بشه

React قبل از اجرای effect جدید، اول cleanup قبلی رو اجرا میکنه.

چه چیزایی Cleanup نمیخوان؟

  • setState ساده

  • محاسبات داخل render

  • چیزایی که subscription یا async نیستن

هر چی resource خارجی یا زماندار باشه → cleanup لازم داره.

چرا اینقدر مهمه؟

چون اگه رعایت نکنی:

❌ memory leak
❌ کند شدن اپ
❌ مصرف زیاد باتری
❌ باگهای عجیب
❌ state آپدیت روی کامپوننت حذفشده

ولی اگه رعایت کنی:

✅ اپ تمیز
✅ رفتار قابل پیشبینی
✅ performance بهتر
✅ کد حرفهایتر

جمعبندی

هر چیزی که داخل useEffect راه میندازی از خودت بپرس:

اگه این صفحه بسته شد، باید اینو خاموش کنم یا نه؟

اگه جواب "آره" بود → حتماً cleanup بنویس. ممنون که خوندی.

reactreact nativenextjshookperformance
۳
۰
مهدی فرجی
مهدی فرجی
شاید از این پست‌ها خوشتان بیاید