مقدمه: چرا React Hooks دنیای ما را تغییر داد؟

قبل از معرفی هوک‌ها در نسخه ۱۶.۸ ری‌اکت، توسعه‌دهندگان برای مدیریت وضعیت (State) و چرخه حیات (Lifecycle) مجبور بودند از Class Components استفاده کنند. اگرچه کلاس‌ها قدرتمند بودند، اما با بزرگ شدن پروژه‌ها، مدیریت منطق‌های مشترک، پیچیدگی در استفاده از this و مشکلاتی مثل "Wrapper Hell" (تولید کامپوننت‌های تودرتوی زیاد برای بازاستفاده از منطق) باعث کلافگی توسعه‌دهندگان می‌شد.

ظهور React Hooks یک پارادایم جدید را معرفی کرد که به ما اجازه می‌دهد در کامپوننت‌های تابعی (Functional Components)، از ویژگی‌هایی که قبلاً فقط در کلاس‌ها در دسترس بودند، استفاده کنیم. این یعنی کد شما تمیزتر، کوچک‌تر و بسیار قابل‌فهم‌تر خواهد بود.

۱. هوک‌های پایه: ستون‌های اصلی ری‌اکت

useState: مدیریت وضعیت در کامپوننت‌های تابعی

هوک useState ساده‌ترین و پرکاربردترین هوک است. این هوک به شما اجازه می‌دهد تا متغیرهایی تعریف کنید که با تغییر آن‌ها، ری‌اکت به صورت خودکار کامپوننت را دوباره رندر (Re-render) می‌کند.

const [state, setState] = useState(initialValue);

در این ساختار، state مقدار فعلی و setState تابعی است که برای به‌روزرسانی آن استفاده می‌شود. یک نکته بسیار مهم در مورد useState، استفاده از Functional Updates است. زمانی که وضعیت جدید شما به وضعیت قبلی وابسته است، حتماً باید از فرم تابعی استفاده کنید تا از مشکلات Race Condition جلوگیری شود:

setState(prevState => prevState + 1);

useEffect: مدیریت اثرات جانبی (Side Effects)

در دنیای برنامه‌نویسی، "اثر جانبی" یعنی هر چیزی که خارج از بازگشت یک تابع باشد؛ مثل فراخوانی یک API، تغییر DOM دستی، یا تنظیم یک تایمر. هوک useEffect جایگزین متدهای componentDidMount، componentDidUpdate و componentWillUnmount شده است.

  • بدون آرایه وابستگی: در هر رندر اجرا می‌شود.
  • آرایه خالی [ ] : فقط یک بار پس از اولین رندر اجرا می‌شود (مشابه componentDidMount).
  • دارای وابستگی [dep] : تنها زمانی اجرا می‌شود که مقدار dep تغییر کند.
نکته حرفه‌ای: همیشه فراموش نکنید که در useEffect، اگر از addEventListener یا setInterval استفاده کردید، حتماً یک تابع Cleanup برگردانید تا از Memory Leak جلوگیری شود.

۲. هوک‌های بهینه‌سازی: افزایش سرعت اپلیکیشن

یکی از بزرگترین چالش‌ها در ری‌اکت، رندرهای غیرضروری است. وقتی یک کامپوننت والد رندر می‌شود، تمام فرزندان آن نیز رندر می‌شوند، مگر اینکه از روش‌های بهینه‌سازی استفاده کنید.

useMemo: ذخیره‌سازی نتایج محاسبات سنگین

اگر تابعی دارید که محاسبات بسیار سنگینی انجام می‌دهد، نباید اجازه دهید در هر رندر دوباره اجرا شود. useMemo مقدار خروجی یک تابع را ذخیره (Memoize) می‌کند و تنها زمانی آن را دوباره محاسبه می‌کند که وابستگی‌های مشخص شده تغییر کرده باشند.

useCallback: حفظ مرجع توابع

تفاوت useMemo و useCallback در اینجاست که useMemo یک مقدار را ذخیره می‌کند، اما useCallback خودِ تابع را ذخیره می‌کند. در ری‌اکت، هر بار که کامپوننت رندر می‌شود، توابع داخل آن دوباره ساخته می‌شوند. این موضوع باعث می‌شود که اگر تابعی را به عنوان Props به یک کامپوننت فرزند (که با React.memo بهینه‌سازی شده) پاس دهید، آن فرزند تصور کند تابع تغییر کرده و دوباره رندر شود. useCallback با حفظ ارجاع (Reference) تابع، این مشکل را حل می‌کند.

۳. مدیریت وضعیت‌های پیچیده و داده‌های سراسری

useReducer: جایگزین قدرتمند برای useState

وقتی وضعیت (State) شما از چند بخش مختلف تشکیل شده یا منطق تغییر وضعیت بسیار پیچیده است، استفاده از چندین useState کد را کثیف می‌کند. در اینجا useReducer وارد عمل می‌شود. این هوک مشابه الگوی Redux عمل می‌کند و از یک reducer برای مدیریت تمام تغییرات بر اساس actionها استفاده می‌کند.

useContext: خداحافظی با Prop Drilling

یکی از دردسرهای بزرگ در توسعه فرانت‌اند، پاس دادن داده‌ها از طریق چندین لایه کامپوننت (Prop Drilling) است. useContext به شما اجازه می‌دهد داده‌ها را در یک "Context" قرار دهید و هر کامپوننتی که در هر سطحی از درخت کامپوننت‌ها قرار دارد، مستقیماً به آن دسترسی داشته باشد.

۴. هوک‌های پیشرفته و کاربردی دیگر

useRef: دسترسی مستقیم به DOM و ذخیره مقادیر بدون رندر

هوک useRef دو کاربرد اصلی دارد: اول، دسترسی مستقیم به عناصر DOM (مثل فوکوس کردن روی یک Input). دوم، ذخیره کردن مقداری که می‌خواهید در طول چرخه حیات کامپوننت باقی بماند، اما تغییر آن باعث رندر مجدد کامپوننت نشود.

۵. قوانین حیاتی (Rules of Hooks)

برای اینکه هوک‌ها درست کار کنند، باید دو قانون طلایی را رعایت کنید:

  1. فقط در سطح بالا فراخوانی کنید: هرگز هوک‌ها را داخل حلقه‌ها، شرط‌ها یا توابع تو در تو قرار ندهید. ری‌اکت بر اساس ترتیب فراخوانی هوک‌ها، وضعیت‌ها را مدیریت می‌کند.

... ادامه مقاله در وبسایت AUAZ.ir