آموزش کامل React Hooks برای مبتدیان

React Hooks - برنامه‌نویسی React

React Hooks یکی از بزرگ‌ترین تغییرات در اکوسیستم React از نسخه 16.8 به بعد است. هدف آن ساده‌تر کردن مدیریت وضعیت (state) و چرخه‌ی عمر کامپوننت‌هاست، بدون نیاز به کلاس‌ها.

۱. React Hooks چیست؟

در گذشته برای مدیریت state و lifecycle باید از کلاس‌ کامپوننت‌ها استفاده می‌کردیم. اما کلاس‌ها گاهی پیچیده و پر از boilerplate بودند. با معرفی Hooks، امکان استفاده از state، lifecycle و دیگر قابلیت‌های React در کامپوننت‌های تابعی (Functional Components) فراهم شد.

💡
به زبان ساده: Hooks به شما اجازه می‌دهند بدون نوشتن کلاس، از قابلیت‌های قدرتمند React استفاده کنید.

۲. چرا باید از Hooks استفاده کنیم؟

مزایای اصلی React Hooks عبارتند از:

  • کد کمتر و خواناتر: دیگر نیازی به متدهای کلاس مانند constructor یا this.state نیست
  • منطقی‌تر بودن جریان داده‌ها: می‌توانید منطق مرتبط با یک ویژگی را درون یک hook جدا کنید
  • قابلیت استفاده مجدد: می‌توانید Hookهای سفارشی (Custom Hooks) بسازید
  • سازگاری با آینده React: بسیاری از کتابخانه‌ها بر پایه‌ی Hooks طراحی شده‌اند

۳. شروع کار: useState

اولین و ساده‌ترین Hook، useState است. این Hook برای مدیریت state محلی در یک کامپوننت تابعی استفاده می‌شود.

import { useState } from "react";

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

  return (
    <div>
      <p>شمارنده: {count}</p>
      <button onClick={() => setCount(count + 1)}>
        افزایش
      </button>
    </div>
  );
}

export default Counter;
🔹
در کد بالا:
  • useState(0) مقدار اولیه state را تعیین می‌کند
  • تابع setCount برای به‌روزرسانی مقدار استفاده می‌شود
  • هر بار که state تغییر کند، کامپوننت دوباره رندر می‌شود

۴. مدیریت چرخه‌ی عمر با useEffect

Hook بعدی، useEffect، برای انجام عملیات جانبی (side effects) مانند فراخوانی API، تایمرها، یا دسترسی به DOM به کار می‌رود.

import { useState, useEffect } from "react";

function UsersList() {
  const [users, setUsers] = useState([]);

  useEffect(() => {
    fetch("https://jsonplaceholder.typicode.com/users")
      .then((res) => res.json())
      .then((data) => setUsers(data));
  }, []); // وابستگی خالی = فقط یک بار اجرا

  return (
    <ul>
      {users.map((user) => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  );
}

export default UsersList;
⚠️
نکته مهم: آرایه‌ی دوم در useEffect مشخص می‌کند چه زمانی effect دوباره اجرا شود. اگر آن را خالی بگذارید []، effect فقط یک بار در زمان mount اجرا می‌شود.

۵. استفاده از useRef

useRef برای گرفتن ارجاع مستقیم به عناصر DOM یا ذخیره‌ی مقادیری که با تغییر آن‌ها، کامپوننت نباید دوباره رندر شود، استفاده می‌شود.

import { useRef } from "react";

function FocusInput() {
  const inputRef = useRef();

  const handleFocus = () => {
    inputRef.current.focus();
  };

  return (
    <div>
      <input ref={inputRef} type="text" />
      <button onClick={handleFocus}>فکوس کن</button>
    </div>
  );
}

export default FocusInput;
🔹
ویژگی کلیدی:
  • مقدار useRef در طول عمر کامپوننت ثابت باقی می‌ماند
  • تغییر مقدار ref.current باعث رندر مجدد نمی‌شود

۶. استفاده از useContext

اگر داده‌ای دارید که بین چند کامپوننت مشترک است (مثلاً زبان سایت، وضعیت ورود، یا تم رنگی)، از useContext استفاده کنید.

import { createContext, useContext } from "react";

const ThemeContext = createContext("light");

function Button() {
  const theme = useContext(ThemeContext);
  return <button className={theme}>دکمه</button>;
}

function App() {
  return (
    <ThemeContext.Provider value="dark">
      <Button />
    </ThemeContext.Provider>
  );
}

🔹 این روش جایگزین ساده‌ای برای Prop Drilling است و باعث تمیزتر شدن کد می‌شود.

۷. ساخت Hook سفارشی (Custom Hook)

Hookهای سفارشی برای زمانی مفیدند که می‌خواهید منطق قابل‌استفاده‌ی مجدد بسازید. مثلاً یک Hook برای تشخیص وضعیت آنلاین بودن کاربر:

import { useState, useEffect } from "react";

function useOnlineStatus() {
  const [isOnline, setIsOnline] = useState(navigator.onLine);

  useEffect(() => {
    const handleOnline = () => setIsOnline(true);
    const handleOffline = () => setIsOnline(false);

    window.addEventListener("online", handleOnline);
    window.addEventListener("offline", handleOffline);

    return () => {
      window.removeEventListener("online", handleOnline);
      window.removeEventListener("offline", handleOffline);
    };
  }, []);

  return isOnline;
}

export default useOnlineStatus;

و در هر کامپوننتی می‌توان از آن استفاده کرد:

function StatusIndicator() {
  const isOnline = useOnlineStatus();
  return <p>وضعیت: {isOnline ? "آنلاین ✅" : "آفلاین ❌"}</p>;
}

۸. قوانین مهم استفاده از Hooks

⚠️
قوانین Hooks:
  • Hooks باید فقط در سطح بالای کامپوننت تابعی فراخوانی شوند
  • ❌ داخل شرط یا حلقه استفاده نکنید
  • فقط در کامپوننت‌های تابعی یا Custom Hooks از آن‌ها استفاده کنید
  • ترتیب فراخوانی Hooks در هر رندر باید یکسان باشد

۹. Hookهای پرکاربرد دیگر

Hook کاربرد
useReducer جایگزینی قدرتمند برای useState در stateهای پیچیده
useMemo جلوگیری از محاسبات غیرضروری و بهینه‌سازی عملکرد
useCallback جلوگیری از ساخت مجدد توابع در هر رندر
useLayoutEffect مشابه useEffect اما قبل از رسم صفحه اجرا می‌شود
useId ایجاد شناسه‌ی منحصربه‌فرد برای عناصر فرم‌ها

۱۰. جمع‌بندی

React Hooks نحوه‌ی نوشتن کامپوننت‌ها را متحول کرده‌اند. با استفاده از آن‌ها می‌توانید کدهای ساده‌تر، قابل نگهداری‌تر و قابل‌استفاده‌ی مجدد بنویسید.

"اگر تازه‌کار هستید، پیشنهاد می‌شود ابتدا با useState و useEffect شروع کنید و به‌مرور سراغ Hookهای پیشرفته‌تر بروید."

- توصیه‌های React Team

درک درست از Hooks به شما کمک می‌کند پروژه‌های حرفه‌ای‌تری بسازید و از آخرین قابلیت‌های React به بهترین شکل بهره ببرید.

🎉
تبریک! حالا با React Hooks آشنا شدید. تمرین کنید و پروژه‌های واقعی بسازید تا مهارت خود را تقویت کنید!
ترنم

ترنم کمالی پناه

توسعه‌دهنده فرانت‌اند و طراح UI/UX. علاقه‌مند به React و تکنولوژی‌های مدرن JavaScript. در این بلاگ تجربیات و دانش خود را به اشتراک می‌گذارم.