در ریاکت وقتی از useEffect استفاده میکنیم داریم یک «اثر جانبی» ایجاد میکنیم؛ مثل تایمر، event listener یا درخواست شبکه. نکتهی مهم این است که این اثرها نباید بعد از رندرهای جدید یا حذف شدن کامپوننت فعال بمانند. برای همین ریاکت مفهومی به نام clean-up دارد.
Clean-up همان تابعی است که از داخل useEffect برمیگردانیم و در دو زمان اجرا میشود:
قبل از اجرای افکت جدید (وقتی وابستگیها تغییر میکنند)
قبل از Unmount شدن کامپوننت
یعنی هر چیزی که در افکت میسازیم، باید اینجا پاک شود.
useEffect(() => { const timer = setTimeout(() => { if (searchValue) { handleSearch(); } }, 500); return () => { clearTimeout(timer); }; }, [searchValue]);
هر بار که کاربر تایپ میکند، رندر جدید باعث اجرای clean-up میشود و تایمر قبلی پاک میشود. اگر کاربر صفحه را ترک کند، clean-up برای آخرین بار اجرا میشود.
در درخواستهای fetch باید درخواست قبلی را هم لغو کنید. این کار با AbortController انجام میشود:
useEffect(() => { const controller = new AbortController(); if (searchValue) { fetch(`/api/search?q=${searchValue}`, { signal: controller.signal, }).catch(() => {}); } return () => controller.abort(); }, [searchValue]);
useEffect(() => { const keyHandler = e => { if (e.key === "Escape") { // do something } }; document.addEventListener("keyup", keyHandler); // clean-up return () => { document.removeEventListener("keyup", keyHandler); }; }, []);
امیدوارم که این مطلب براتون مفید بوده باشه