📚 بخش ۱۸: آشنایی با useState و مدیریت State در کامپوننت‌ها

""

۱. مقدمه — چرا useState مهم است؟

در React نسخه‌های مدرن (خصوصاً از نسخه ۱۶.۸ به بعد)، استفاده از Hooks باعث شد بتوانیم state و امکانات دیگر را به جای Class Component، داخل تابع‌ها هم داشته باشیم.

اولین و مهم‌ترین Hook که همه‌ی توسعه‌دهنده‌ها با آن شروع می‌کنند، useState است.
این Hook به ما این امکان را می‌دهد که داخل یک کامپوننت تابعی (Functional Component) متغیرهایی با قابلیت ذخیره‌سازی حالت و پاسخ به تغییراتشان ایجاد کنیم.


۲. تعریف ساده useState

useState یک تابع از کتابخانه‌ی React است که:

  • یک متغیر state ایجاد می‌کند (برای نگهداری داده)
  • یک تابع setter برای تغییر دادن آن متغیر برمی‌گرداند

ساختار کلی:

const [stateValue, setStateValue] = useState(initialValue);

۳. قدم به قدم — چطور استفاده کنیم؟

۱. هوک را از React ایمپورت می‌کنیم:

import { useState } from 'react';
  1. در داخل تابع کامپوننت فراخوانی می‌کنیم:
const [count, setCount] = useState(0);
  • count → مقدار فعلی
  • setCount → تابعی برای تغییر مقدار
  • 0 → مقدار اولیه state

۴. مثال ساده: شمارنده

import { useState } from 'react';

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

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

export default Counter;

تحلیل خط به خط

  • useState(0) → state اولیه را صفر قرار می‌دهد.
  • setCount(count + 1) → تابعی که state را تغییر می‌دهد.
  • وقتی state تغییر کند، React همان کامپوننت را دوباره رندر می‌کند و مقدار count جدید را نمایش می‌دهد.

۵. نکات کلیدی در استفاده از useState

  • هر بار که setState فراخوانی شود:
  1. مقدار state تغییر می‌کند.
  2. کامپوننت مجدد رندر می‌شود.
  • تغییر مستقیم state بدون استفاده از setter کار نمی‌کند:
count = count + 1; // ⛔ کار اشتباه
  • اگر state جدید بر اساس state قبلی محاسبه می‌شود، از Callback Form استفاده کنید:
setCount(prev => prev + 1);

این روش مطمئن است چون از مقدار قبلی در همان لحظه استفاده می‌کند، حتی اگر چند به‌روزرسانی هم‌زمان باشند.


۶. مثال: فیلد ورودی

function NameInput() {
  const [name, setName] = useState('');

  return (
    <div>
      <input 
        value={name}
        onChange={e => setName(e.target.value)}
        placeholder="نام خود را وارد کنید"
      />
      <p>نام شما: {name}</p>
    </div>
  );
}

📌 اینجا داریم از useState برای ذخیره رشته‌ ورودی کاربر استفاده می‌کنیم.


۷. State می‌تواند هر نوع داده‌ای باشد

  • رشته (string):
const [text, setText] = useState("سلام");
  • عدد (number):
const [count, setCount] = useState(0);
  • بولین (boolean):
const [isOpen, setIsOpen] = useState(false);
  • آرایه (array):
const [items, setItems] = useState([]);
  • شیء (object):
const [user, setUser] = useState({ name: '', age: 0 });

۸. نکته مهم — بروزرسانی state های پیچیده

وقتی state یک آبجکت یا آرایه است، باید نسخه جدیدش را بسازیم چون state در React Immutable است.

مثلاً برای تغییر شیء:

setUser(prev => ({ ...prev, name: "علی" }));

برای اضافه کردن آیتم به آرایه:

setItems(prev => [...prev, "آیتم جدید"]);

۹. مثال پیشرفته — مدیریت چند state

function ProfileForm() {
  const [name, setName] = useState('');
  const [age, setAge] = useState('');
  const [skills, setSkills] = useState([]);

  const addSkill = skill => {
    setSkills(prev => [...prev, skill]);
  };

  return (
    <div>
      <input 
        value={name} 
        onChange={e => setName(e.target.value)}
        placeholder="نام" 
      />
      <input 
        type="number" 
        value={age} 
        onChange={e => setAge(e.target.value)}
        placeholder="سن" 
      />
      <button onClick={() => addSkill("React")}>افزودن مهارت React</button>
      <p>{name} - {age} سال</p>
      <ul>
        {skills.map((s, i) => <li key={i}>{s}</li>)}
      </ul>
    </div>
  );
}

۱۰. اشتباهات رایج

تغییر مستقیم state

user.name = "جدید"; // 🔴 اشتباه

✅ باید نسخه کپی بسازیم:

setUser(prev => ({ ...prev, name: "جدید" }));

به‌روزرسانی پشت سرهم بدون استفاده از prev state
ممکن است مقدار اشتباهی ثبت شود اگر از حالت callback استفاده نکنید.


۱۱. تمرین‌های پیشنهادی

۱. Counter با محدودیت: شمارنده بساز که از ۰ پایین‌تر و از ۱۰ بالاتر نرود.
۲. لیست خرید: ورودی + دکمه اضافه کردن محصول به آرایه موجودی.
۳. تغییر حالت تم صفحه: دکمه‌ای که بین حالت تاریک و روشن سوییچ کند (boolean state).


۱۲. نکات حرفه‌ای

  • اگر state شما بسیار پیچیده شد، بهتر است به جای useState از useReducer استفاده کنید.
  • برای کامپوننت‌هایی که زیاد رندر می‌شوند، مطمئن شوید تغییر state واقعاً لازم است.
  • state باید فقط اطلاعاتی را نگه دارد که بر رابط کاربری تأثیر می‌گذارد.

۱۳. جمع‌بندی

  • useState قلب مدیریت داده در کامپوننت‌های تابعی است.
  • همیشه برای تغییر state از تابع setter استفاده کن.
  • state در React immutable است، پس همیشه نسخه جدید بساز.
  • نوع داده‌ی state می‌تواند هرچیزی باشد: رشته، عدد، بولین، آرایه یا شیء.
  • تغییر state باعث رندر مجدد کامپوننت می‌شود.
محمد وب‌سایت

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *