مقدمه

در درس قبل، با هوک useState برای افزودن «حافظه» یا state به کامپوننت‌هایمان آشنا شدیم. دیدیم که با فراخوانی تابع setter (مانند setCount)، رابط کاربری به‌روز می‌شود. اما در پشت صحنه دقیقاً چه اتفاقی می‌افتد؟ درک فرآیند «رندر مجدد» یا re-render یکی از کلیدی‌ترین مفاهیم برای تسلط بر React است.

فرآیند رندر در React

«رندر کردن» در React به فرآیندی گفته می‌شود که در آن، React کامپوننت‌های شما را فراخوانی کرده و UI متناظر با state و props فعلی را محاسبه می‌کند. این فرآیند در دو حالت اصلی رخ می‌دهد:

  • رندر اولیه (Initial Render): زمانی که اپلیکیشن شما برای اولین بار بارگذاری می‌شود، React کامپوننت ریشه (App) و تمام کامپوننت‌های فرزند آن را برای ساخت DOM اولیه فراخوانی می‌کند.
  • رندر مجدد (Re-render): هر زمان که state یک کامپوننت با استفاده از تابع setter آن به‌روزرسانی شود، React یک رندر مجدد را برای آن کامپوننت و تمام کامپوننت‌های فرزند آن به صف اضافه می‌کند.

یک مثال گام به گام

بیایید دوباره به مثال شمارنده نگاه کنیم و ببینیم با هر کلیک چه اتفاقی می‌افتد:

Copy Icon JAVASCRIPT (React)
const [count, setCount] = useState(0);

// ...
<button onClick={() => setCount(count + 1)}>Click me</button>
  1. کلیک کاربر: کاربر روی دکمه کلیک می‌کند و رویداد onClick اجرا می‌شود.
  2. فراخوانی setter: تابع setCount(count + 1) (که در این لحظه setCount(1) است) فراخوانی می‌شود.
  3. درخواست رندر مجدد: React با دریافت این درخواست، یک رندر مجدد را برای کامپوننت Counter در صف قرار می‌دهد.
  4. اجرای مجدد کامپوننت: React تابع کامپوننت Counter را دوباره فراخوانی می‌کند.
  5. دریافت state جدید: این بار، فراخوانی useState(0) مقدار فعلی state را که 1 است، برمی‌گرداند. بنابراین، [1, f] بازگردانده شده و count اکنون برابر با 1 است.
  6. محاسبه Virtual DOM: ری‌اکت JSX را با count جدید (که 1 است) محاسبه کرده و یک درخت Virtual DOM جدید می‌سازد.
  7. مقایسه و به‌روزرسانی DOM: ری‌اکت این Virtual DOM جدید را با نسخه قبلی مقایسه کرده، تشخیص می‌دهد که تنها محتوای متنی تگ <p> از "0" به "1" تغییر کرده، و تنها همان بخش از DOM واقعی را به‌روزرسانی می‌کند.

state به عنوان یک عکس فوری (Snapshot)

یک نکته بسیار مهم که باید به خاطر بسپارید این است که متغیر state در هر رندر، مانند یک «عکس فوری» (snapshot) و ثابت است. مقدار آن در طول یک رندر هرگز تغییر نمی‌کند، حتی اگر تابع setter آن فراخوانی شود.

Copy Icon JAVASCRIPT (React)
function Counter() {
  const [count, setCount] = useState(0);

  function handleClick() {
    setCount(count + 1); // Request a re-render with 1
    setCount(count + 1); // Request a re-render with 1
    setCount(count + 1); // Request a re-render with 1
    console.log(count); // Still logs 0!
  }
  // ... return JSX
}

اگر روی دکمه در این مثال کلیک کنید، شمارنده تنها یک واحد افزایش می‌یابد، نه سه واحد! دلیل آن این است که در طول اجرای handleClick در آن رندر خاص، مقدار count همیشه 0 است. هر سه فراخوانی setCount یک رندر مجدد با مقدار 1 را درخواست می‌کنند. React این درخواست‌های تکراری را با هم ادغام کرده و تنها یک بار کامپوننت را با state جدید (1) رندر می‌کند.

برای به‌روزرسانی state بر اساس مقدار قبلی آن، باید از یک «تابع به‌روزرسان» (updater function) استفاده کنیم که در درس‌های آینده به آن خواهیم پرداخت.

در این درس، با فرآیند رندر مجدد در React و نحوه عملکرد آن پس از تغییر state آشنا شدیم. درک این مکانیزم که state به عنوان یک عکس فوری در هر رندر عمل می‌کند، برای فهم رفتار React و جلوگیری از باگ‌های رایج بسیار حیاتی است. در درس بعدی، به «مدیریت چند state در یک کامپوننت» خواهیم پرداخت و خواهیم دید که چگونه می‌توان چندین متغیر state مستقل را در یک کامپوننت تعریف و مدیریت کرد.