• صفحه اصلی
  • مهارت‌ها
  • پروژه‌ها
  • بلاگ
  • مشاوره
  • تماس با من
مشاورهرزومه
Naser Rasouli

نویسنده

Naser Rasouli

توسعه‌دهنده فرانت‌اند؛ اینجا تجربه‌ها و یادداشت‌های واقعی‌ام از پروژه‌ها را می‌نویسم.

GitHubLinkedIn

آخرین نوشته‌ها

متدولوژی BEM در CSS: نام‌گذاری استاندارد برای کدهای تمیز
2026-02-18•1 دقیقه مطالعه

متدولوژی BEM در CSS: نام‌گذاری استاندارد برای کدهای تمیز

راهنمای عملی BEM برای جلوگیری از تداخل استایل، ساختاردهی کلاس‌ها و نگهداری ساده‌تر CSS.

تابع Cleanup در useEffect: از باگ‌های پنهان تا الگوهای درست
2026-02-04•1 دقیقه مطالعه

تابع Cleanup در useEffect: از باگ‌های پنهان تا الگوهای درست

راهنمای عملی نوشتن cleanup در useEffect تا از memory leak، لیسنرهای تکراری و setState روی کامپوننت unmounted جلوگیری کنید.

مسیر مصاحبه فرانت‌اند: مراحل، انتظارها و آماده‌سازی
2026-01-17•1 دقیقه مطالعه

مسیر مصاحبه فرانت‌اند: مراحل، انتظارها و آماده‌سازی

مصاحبه فرانت‌اند فقط چند سؤال دربارهٔ HTML و JavaScript نیست؛ مسیری است برای سنجش فهم وب، حل مسئله و توان همکاری. این راهنما مراحل رایج و انتظارات هر بخش را خلاصه می‌کند.

بررسی نحوه به‌روزرسانی state در React

بررسی نحوه به‌روزرسانی state در React

2026-02-11
reactstatesetStatehooksuseEffect

مقدمه

اگر در React بعد از setState یا setCount لاگ بگیرید و مقدار قبلی را ببینید، باگ نیست. React عمداً آپدیت‌ها را غیرهمزمان و batch می‌کند تا رندرهای اضافه نداشته باشد. در این نوشته می‌بینیم چرا این اتفاق طبیعی است و چطور مقدار جدید state را درست بخوانیم.


چرا state بلافاصله عوض نمی‌شود؟

  • setState بلافاصله مقدار را تغییر نمی‌دهد؛ فقط یک درخواست آپدیت در صف می‌گذارد.
  • جاوااسکریپت ادامه اجرا می‌شود و React بعداً در چرخهٔ رندر بعدی state جدید را اعمال می‌کند.
  • بنابراین هر کدی که فوراً بعد از setState اجرا شود، هنوز به مقدار قدیمی دسترسی دارد.

فلو سادهٔ پشت‌صحنه:

  1. setCount صدا زده می‌شود.
  2. React آپدیت را در صف می‌گذارد.
  3. بقیهٔ کد همان لحظه اجرا می‌شود.
  4. رندر جدید انجام می‌شود و state تازه در دسترس قرار می‌گیرد.

مثال پایه

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

const handleClick = () => {
  setCount(count + 1);
  console.log(count); // هنوز مقدار قبلی است
};

چون console.log قبل از رندر جدید اجرا می‌شود، خروجی همچنان 0 است.


چطور مقدار جدید را ببینیم؟

استفاده از useEffect

useEffect(() => {
  console.log(count); // همیشه مقدار به‌روز
}, [count]);

useEffect بعد از رندر اجرا می‌شود، پس لاگ همیشه state تازه را نشان می‌دهد.

استفاده از Functional Update

وقتی مقدار جدید به مقدار قبلی وابسته است، فرم تابعی همیشه آخرین state را می‌دهد:

setCount(prev => {
  const next = prev + 1;
  console.log(next); // مقدار جدید همین‌جاست
  return next;
});

چند آپدیت پشت‌سرهم

اشتباه رایج:

setCount(count + 1);
setCount(count + 1); // هر دو از مقدار قدیمی استفاده می‌کنند

نتیجه فقط +1 است. نسخهٔ درست:

setCount(prev => prev + 1);
setCount(prev => prev + 1); // مجموعاً +2

فرم تابعی تضمین می‌کند هر آپدیت روی تازه‌ترین مقدار اعمال شود.


کجاها حواسمان باید باشد؟

  • لاگ گرفتن بلافاصله بعد از setState
  • ارسال state به API بلافاصله بعد از آپدیت
  • شرط‌گذاری با state قدیمی (مثلاً بلافاصله در همان تابع)
  • چند آپدیت متوالی روی یک state بدون فرم تابعی

در همهٔ این حالت‌ها یا از useEffect استفاده کنید یا از functional update.


چک‌لیست سریع

  • آیا آپدیت به مقدار قبلی وابسته است؟ → از فرم تابعی استفاده کن.
  • نیاز داری مقدار به‌روز را ببینی؟ → داخل useEffect روی همان state لاگ بگیر.
  • چند آپدیت پشت‌سرهم داری؟ → همه را به صورت تابعی بنویس تا batching درست کار کند.

جمع‌بندی

مشاهدهٔ مقدار قدیمی بعد از setState رفتاری عمدی است، نه ایراد. React آپدیت‌ها را صف و batch می‌کند؛ به همین دلیل باید یا منتظر رندر بعدی بمانید (useEffect) یا از functional update استفاده کنید تا به مقدار جدید دسترسی داشته باشید. قانون ساده: «اگر به state قبلی نیاز داری، تابعی بنویس؛ اگر می‌خواهی state جدید را ببینی، بعد از رندر سراغش برو.»