مقدمه

به فصل نهم خوش آمدید! فرم‌ها یکی از اصلی‌ترین راه‌های تعامل کاربر با یک اپلیکیشن وب هستند. از فرم‌های ورود و ثبت‌نام گرفته تا فرم‌های جستجو و ارسال نظر، همگی به ما اجازه می‌دهند تا داده‌ها را از کاربر دریافت کنیم. در React، مدیریت فرم‌ها با استفاده از الگویی به نام «کامپوننت‌های کنترل‌شده» (Controlled Components) انجام می‌شود.

در این الگو، state کامپوننت React به عنوان «تنها منبع حقیقت» (single source of truth) برای مقدار فیلدهای ورودی عمل می‌کند. هر تغییری در ورودی، state را به‌روزرسانی کرده و هر به‌روزرسانی در state، مقدار ورودی را دوباره رندر می‌کند.

یک فرم ساده HTML

در HTML سنتی، عناصر فرم مانند <input> و <textarea> معمولاً وضعیت داخلی خود را مدیریت می‌کنند. وقتی کاربر چیزی تایپ می‌کند، خود عنصر DOM مقدار جدید را نگه می‌دارد.

Copy Icon HTML
<form>
  <label>
    Name:
    <input type="text" name="name" />
  </label>
  <input type="submit" value="Submit" />
</form>

در این حالت، DOM مقدار فیلد ورودی را کنترل می‌کند. در React، ما این کنترل را به کامپوننت خود واگذار می‌کنیم.

پیاده‌سازی یک کامپوننت کنترل‌شده

برای ساخت یک کامپوننت کنترل‌شده، ما سه مرحله اصلی را طی می‌کنیم:

  1. یک متغیر state برای نگهداری مقدار فعلی ورودی تعریف می‌کنیم.
  2. مقدار state را به اتریبیوت value عنصر ورودی پاس می‌دهیم.
  3. یک event handler برای رویداد onChange تعریف می‌کنیم که با هر تغییر، state را به‌روزرسانی کند.
Copy Icon JAVASCRIPT (React)
import { useState } from 'react';

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

  function handleChange(event) {
    setName(event.target.value);
  }

  function handleSubmit(event) {
    alert('A name was submitted: ' + name);
    event.preventDefault();
  }

  return (
    <form onSubmit={handleSubmit}>
      <label>
        Name:
        <input type="text" value={name} onChange={handleChange} />
      </label>
      <input type="submit" value="Submit" />
    </form>
  );
}

در این مثال، ما یک state به نام name با مقدار اولیه رشته خالی داریم. اتریبیوت value عنصر <input> همیشه برابر با مقدار فعلی state ما (name) است.

وقتی کاربر در فیلد ورودی تایپ می‌کند، رویداد onChange اجرا شده و تابع handleChange فراخوانی می‌شود. این تابع مقدار جدید را از event.target.value خوانده و با setName، state را به‌روزرسانی می‌کند. این به‌روزرسانی باعث رندر مجدد کامپوننت شده و مقدار جدید در فیلد ورودی نمایش داده می‌شود. این چرخه تضمین می‌کند که state کامپوننت و UI همیشه با هم هماهنگ هستند.

مزایای کامپوننت‌های کنترل‌شده

این الگو ممکن است در ابتدا کمی پرجزئیات به نظر برسد، اما مزایای بزرگی دارد:

  • دسترسی فوری به داده‌ها: شما همیشه به مقدار فعلی ورودی از طریق متغیر state خود دسترسی دارید و نیازی به پرس و جو از DOM ندارید.
  • اعتبارسنجی در لحظه: شما می‌توانید با هر بار تغییر، مقدار ورودی را اعتبارسنجی کرده و بازخورد فوری به کاربر نمایش دهید.
  • کنترل کامل بر ورودی: شما می‌توانید رفتار ورودی را به صورت برنامه‌نویسی کنترل کنید، مثلاً با تبدیل تمام حروف به حروف بزرگ یا محدود کردن تعداد کاراکترها.

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