چرا useEffect دوبار اجرا میشود و چطور باید به درستی با آن برخورد کرد؟ (React JS)
Why useEffect running twice and how to handle it well in React?
من در پروژه ریاکتی که دارم روش کار میکنم، متوجه شدم که تابع useEffect دوبار اجرا میشه، حتی وقتی وابستگیهای اون تغییری نکردن. این رفتار باعث شده که برخی عملیاتهایی که نباید چندبار اجرا بشن، دوباره انجام بشن و مشکلاتی رو به وجود بیاره. این مشکل مخصوصاً زمانی که از useEffect برای فراخوانی API یا تنظیمات اولیه استفاده میکنم، مشکلساز میشه. دلیل این موضوع چیه و چطور میتونم این رفتار رو به درستی مدیریت کنم؟
خب، تو ریاکت 18 و بالاتر، وقتی از حالت توسعه (Development Mode) استفاده میکنی، useEffect دوبار اجرا میشه. این کار به خاطر ویژگی "Strict Mode" هست که ریاکت اون رو برای شناسایی باگها و مشکلات احتمالی به کار میبره. یعنی وقتی useEffect دوبار اجرا میشه، میتونی مطمئن بشی که کدت به درستی بدون اثرات جانبی ناخواسته کار میکنه.
برای اینکه این مشکل رو حل کنی یا بهتر مدیریت کنی، میتونی این کارها رو انجام بدی:
- استفاده از Strict Mode فقط در محیط تولید: اگه این رفتار رو نمیخوای، میتونی "Strict Mode" رو فقط در حالت توسعه نگه داری و تو محیط تولید ازش استفاده نکنی. اما بهتره این کارو نکنی چون به کمک این ویژگی میتونی مطمئن بشی که کدت درست و بدون باگهای پنهان کار میکنه.
- مدیریت side effectها: اگر فراخوانیهای useEffect برای API یا عملیاتهای مهم دیگه است، میتونی با اضافه کردن یک شرط یا نشانه (flag) جلوی اجرای دوباره اونا رو بگیری. مثلاً میتونی یک متغیر state یا ref اضافه کنی که نشون بده آیا این عملیات قبلاً انجام شده یا نه.
useEffect(() => { if (!alreadyFetched) { fetchData(); setAlreadyFetched(true); } }, [dependencies]);
- بهینهسازی با استفاده از Cleanup: اگه لازم داری، میتونی از یک تابع cleanup توی useEffect استفاده کنی تا اثرات جانبی ناخواسته پاک بشن.مثال:
useEffect(() => { const controller = new AbortController(); fetchData(controller.signal); return () => controller.abort(); }, [dependencies]);
در نهایت، با اینکه این رفتار ممکنه اذیتکننده باشه، اما به تو کمک میکنه که کدهای قابل اعتمادتر و بهتر بنویسی. اگر خیلی این موضوع اذیتت میکنه و میخوای برای محیط توسعه این رفتار رو غیرفعال کنی، میتونی StrictMode رو از پروژهت برداری، ولی پیشنهاد میکنم حتماً اون رو در محیط تولید فعال نگه داری.
با این راهکارها، میتونی رفتار useEffect رو بهتر مدیریت کنی و از بروز مشکلات احتمالی جلوگیری کنی.
این جواب به طور کامل مشکلاتی که ممکنه با useEffect داشته باشی رو پوشش میده و بهت کمک میکنه تا کدت رو بهینهتر و بهتر بنویسی.