پیش از رفتن سراغ مثالها، مهم است تفاوت state و ref را در React خوب بفهمیم.
🔵 State در برابر 🔴 Ref (درک سریع)
🔵 State دادهای است که رابط کاربری شما را تعریف میکند. تغییرش باعث رندر دوباره میشود، React کاملاً رابط کاربری را کنترل میکند و برای منطق اپلیکیشن استفاده میشود. 👉 اگر روی چیزی که کاربر بر اساس وضعیت اپ میبیند اثر دارد، باید state باشد.
🔴 Ref ارجاع مستقیم به یک عنصر DOM یا یک مقدار تغییرپذیر است. رندر دوباره ایجاد نمیکند، React تغییراتش را دنبال نمیکند و برای کارهای دستوری استفاده میشود. 👉 اگر فقط یک تعامل مستقیم با DOM یا یک افکت موقت است، ref کافی است.
🔵 ۱. State — رابط کاربری تحت کنترل React
state یعنی React رابط کاربری را بر اساس تغییر داده رندر میکند. کاربردها: لایک/آنلایک، باز و بسته شدن مودال، وضعیت حذف، مدیریت فرم.
const [isLiked, setIsLiked] = useState(false);
<button onClick={() => setIsLiked(!isLiked)}>
{isLiked ? "❤️ Liked" : "🤍 Like"}
</button>👉 رابط کاربری کاملاً با state هدایت میشود.
🔴 ۲. Ref — کنترل مستقیم DOM
ref اجازه میدهد عناصر DOM را بدون رندر دوباره React تغییر دهید. کاربردها: فوکوس روی ورودیها، اسکرول، انیمیشنهای دستوری، افکتهای موقت DOM.
const btnRef = useRef(null);
btnRef.current.style.transform = "scale(0.9)";👉 React از این تغییر خبر ندارد.
🟢 ۳. CSS — بهترین برای افکتهای بصری
CSS سادهترین و کارآمدترین راه برای افکتهای رابط کاربری است: افکت هاور، ترنزیشن، انیمیشن و بازخورد کلیک.
.delete-btn:active {
transform: scale(0.9);
background-color: red;
}👉 هیچ جاوااسکریپتی لازم نیست.
⚖️ نکته کلیدی
همه چیز در رابط کاربری نباید state باشد. انتخاب روش اشتباه به رندرهای اضافی، منطق شلوغ و رفتار رابط کاربری سختدیباگ میرسد.
🧩 مثال واقعی: چشمک دکمه حذف
در یک پروژه React به دکمه حذفی نیاز داشتم که پیش از حذف آیتم یک چشمک قرمز کوتاه نشان دهد.
❌ اشتباه: استفاده از state برای همه چیز
const [isFlashing, setIsFlashing] = useState(false);مشکل: یک رندر دوباره غیرضروری — برای یک افکت بصری ۲۰۰ میلیثانیهای زیادی است.
❌ ترکیبی: state + ref
// افکت روی دکمه
btnRef.current.style.backgroundColor = "red";
// حذف کل کامپوننت
setIsDeleting(true);مشکل: دو منبع حقیقت و رفتار ناهماهنگ رابط کاربری.
✅ درست: CSS + تغییر کلاس
const handleDeleteClick = (e) => {
const btn = e.currentTarget;
btn.classList.add("flash");
setIsDeleting(true);
setTimeout(() => {
btn.classList.remove("flash");
handleDelete(id);
}, 200);
};.delete-btn.flash {
background-color: red;
transform: scale(0.9);
}🎯 جمعبندی
- State ← برای داده واقعی اپلیکیشن
- Ref ← برای تغییر مستقیم DOM
- CSS ← برای افکتهای بصری ساده
💡 اگر چیزی وضعیت اپلیکیشن را نشان نمیدهد، احتمالاً نباید state باشد.



