مدیریت State با useState
در React
در React، State (وضعیت) یک مقدار دینامیک است که هنگام تغییر، باعث بهروزرسانی و رندر مجدد کامپوننت میشود.
📌 قبل از React 16.8، فقط کامپوننتهای کلاسی میتوانستند State داشته باشند.
📌 بعد از نسخه 16.8، با معرفی هوکها (Hooks)، میتوان از useState
در کامپوننتهای فانکشنی هم استفاده کرد.
۱. تعریف State با useState
useState
یک آرایه دو عنصری برمیگرداند:
1️⃣ مقدار فعلی State
2️⃣ تابعی برای تغییر مقدار State
ساختار کلی useState
✔ مقدار اولیه initialValue
مقدار پیشفرض State است.
✔ setState
مقدار جدید را تنظیم کرده و کامپوننت را ریرندر میکند.
۲. مثال ساده: شمارنده (Counter)
const 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)
مقدار اولیه را ۰ تنظیم میکند.
✅ setCount(count + 1)
مقدار count
را افزایش داده و باعث ریرندر میشود.
۳. استفاده از مقدار قبلی State
گاهی اوقات باید مقدار جدید را بر اساس مقدار قبلی تنظیم کنیم. در این حالت از کالبک در setState
استفاده میکنیم.
مثال: شمارنده با مقدار قبلی
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(prevCount => prevCount + 1)}>
عدد: {count}
</button>
);
};
✔ در این حالت، مقدار قبلی count
در prevCount
ذخیره شده و مقدار جدید بر اساس آن تنظیم میشود.
۴. مدیریت Stateهای چندگانه
اگر یک کامپوننت چندین State داشته باشد، میتوان از چند useState
جداگانه استفاده کرد.
مثال: مدیریت نام و سن کاربر
const [name, setName] = useState("علی");
const [age, setAge] = useState(25);
return (
<div>
<h2>نام: {name}</h2>
<h2>سن: {age}</h2>
<button onClick={() => setAge(age + 1)}>افزایش سن</button>
</div>
);
};
✔ useState("علی")
مقدار اولیه name
را علی تنظیم میکند.
✔ setAge(age + 1)
مقدار age
را یک واحد افزایش میدهد.
۵. مدیریت آرایه در State
در آرایهها، باید مقدار جدید را جایگزین کل آرایه قبلی کنیم.
مثال: اضافه کردن آیتم به لیست
const [todos, setTodos] = useState(["خرید", "ورزش"]);
const addTodo = () => {
setTodos([...todos, "مطالعه"]); // اضافه کردن "مطالعه" به لیست
};
return (
<div>
<ul>
{todos.map((todo, index) => (
<li key={index}>{todo}</li>
))}
</ul>
<button onClick={addTodo}>افزودن کار</button>
</div>
);
};
✔ setTodos([...todos, "مطالعه"])
یک کپی از آرایه قبلی ساخته و مقدار جدید را اضافه میکند.
✔ در React، نباید مستقیماً State را تغییر داد (مثل todos.push("مطالعه")
).
۶. مدیریت آبجکت در State
در آبجکتها هم باید کپی جدید بسازیم و مقدار جدید را در آن قرار دهیم.
مثال: تغییر مقدار در آبجکت State
const [user, setUser] = useState({ name: "علی", age: 25 });
return (
<div>
<h2>نام: {user.name}</h2>
<h2>سن: {user.age}</h2>
<button onClick={() => setUser({ ...user, age: user.age + 1 })}>
افزایش سن
</button>
</div>
);
};
✔ setUser({ ...user, age: user.age + 1 })
آبجکت جدیدی میسازد و مقدار age
را بهروز میکند.
✔ نباید مستقیماً مقدار user.age
را تغییر دهیم.
۷. مقداردهی اولیه از تابع
اگر مقدار اولیه محاسباتی و سنگین باشد، بهتر است از تابع در useState
استفاده کنیم تا فقط یکبار اجرا شود.
مثال: مقداردهی اولیه با تابع
console.log("محاسبه مقدار اولیه...");
return 10;
};
const Counter = () => {
const [count, setCount] = useState(getInitialCount);
return <h1>{count}</h1>;
};
✔ getInitialCount
فقط یکبار هنگام mount اجرا میشود.
✔ اما اگر useState(getInitialCount())
را بنویسیم، تابع در هر رندر اجرا خواهد شد (مطلوب نیست).
جمعبندی و نکات مهم
✅ useState
برای مدیریت State در فانکشنال کامپوننتها استفاده میشود.
✅ مقدار اولیه میتواند عدد، رشته، آرایه یا آبجکت باشد.
✅ نباید State را مستقیماً تغییر داد؛ بلکه باید کپی جدید ساخت.
✅ برای استفاده از مقدار قبلی State، میتوان از کالبک در setState
استفاده کرد.
✅ مقداردهی اولیه بهتر است با یک تابع انجام شود اگر محاسبات زیادی نیاز دارد.
