Forms في React: التحكم في Inputs خطوة بخطوة

في أي تطبيق حقيقي ستتعامل مع نماذج: تسجيل، تسجيل دخول، بحث، أو إضافة منتج. لذلك يجب فهم كيف نتحكم في Inputs داخل React.

في React، الأفضل أن تجعل المدخلات Controlled، أي أن القيمة تكون مخزّنة في State وتُحدَّث عبر onChange.

ما هو Controlled Component؟

هو input تُدار قيمته من خلال State، وليس من DOM مباشرة. هذا يجعل React يتحكم في البيانات بشكل كامل.

التعريف البسيط: Controlled Component = input قيمته تأتي من State.

مثال بسيط: input مع onChange

import { useState } from "react";

function NameInput() {
  const [name, setName] = useState("");

  return (
    <div>
      <input
        value={name}
        onChange={(e) => setName(e.target.value)}
        placeholder="اكتب اسمك"
      />
      <p>مرحباً {name}</p>
    </div>
  );
}

كل حرف يكتبه المستخدم يتم تخزينه في State. وبما أن قيمة input مرتبطة بالـ State، فالواجهة تبقى متزامنة دائماً.

ما يحدث خطوة بخطوة: عند كل ضغطة على لوحة المفاتيح، ينفّذ React حدث onChange. من خلال e.target.value نقرأ القيمة الجديدة، ثم نحدّثها بـ setName. بعدها React يعيد العرض ويضع القيمة الجديدة داخل input والفقرة معًا.

مثال: التعامل مع onSubmit

function LoginForm() {
  const [email, setEmail] = useState("");

  function handleSubmit(e) {
    e.preventDefault();
    alert("تم إرسال النموذج");
  }

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="email"
        value={email}
        onChange={(e) => setEmail(e.target.value)}
        placeholder="البريد الإلكتروني"
      />
      <button type="submit">إرسال</button>
    </form>
  );
}

هنا أوقفنا السلوك الافتراضي للنموذج باستخدام preventDefault، ثم نفّذنا منطقنا الخاص عند الإرسال.

لو لم نستخدم preventDefault، المتصفح سيعيد تحميل الصفحة ويُفقدنا كل القيم الموجودة في الـ State. لذلك نمنع هذا السلوك ونبقي React هو من يدير العملية.

مثال: أكثر من input باستخدام كائن واحد

function RegisterForm() {
  const [form, setForm] = useState({ name: "", email: "" });

  function handleChange(e) {
    setForm({
      ...form,
      [e.target.name]: e.target.value,
    });
  }

  return (
    <form>
      <input
        name="name"
        value={form.name}
        onChange={handleChange}
        placeholder="الاسم"
      />
      <input
        name="email"
        value={form.email}
        onChange={handleChange}
        placeholder="البريد"
      />
    </form>
  );
}

استخدمنا كائن واحد لتخزين القيم، ثم حدّثنا الحقل المناسب عبر name. هذا يقلل عدد متغيرات الـ State ويجعل الكود مرتبًا.

لاحظ السطر [e.target.name]: e.target.value: هذا يعني أننا نغيّر فقط الحقل الذي كتب فيه المستخدم، مع الحفاظ على باقي القيم باستخدام ...form.

مثال: checkbox و select

function Settings() {
  const [darkMode, setDarkMode] = useState(false);
  const [role, setRole] = useState("user");

  return (
    <div>
      <label>
        <input
          type="checkbox"
          checked={darkMode}
          onChange={(e) => setDarkMode(e.target.checked)}
        />
        وضع ليلي
      </label>

      <select value={role} onChange={(e) => setRole(e.target.value)}>
        <option value="user">مستخدم</option>
        <option value="admin">مدير</option>
      </select>
    </div>
  );
}

checkbox يستخدم checked بدل value. أما select فيتغير عبر value مثل input العادي.

في checkbox، القيمة الحقيقة هي true أو false، لذلك نقرأها من e.target.checked. أما select فيعطي قيمة النص المختار عبر e.target.value مثل أي input.

أخطاء شائعة

  • نسيان ربط input بالـ State (فيصبح غير متحكم فيه).
  • تعديل DOM مباشرة بدل الاعتماد على State.
  • نسيان preventDefault في النماذج.

الأسئلة الشائعة — FAQ

ما هو Controlled Component في React؟

هو input تُدار قيمته عبر State، أي أن React هو المصدر الوحيد للحقيقة.

كيف أقرأ قيمة input في React؟

تستخدم onChange مع e.target.value ثم تخزّن القيمة في State.

لماذا نستخدم preventDefault في النماذج؟

لمنع إعادة تحميل الصفحة عند إرسال النموذج وجعل التطبيق تفاعليًا.

كيف أتعامل مع أكثر من input؟

يمكنك استخدام كائن في State وتحديث الحقول عبر الاسم name لكل input.

ما الفرق بين onChange و onSubmit؟

onChange يُستدعى عند كتابة المستخدم، بينما onSubmit يُستدعى عند إرسال النموذج.

التالي: سننتقل لدرس Loading & Error Handling وكيف نتعامل مع حالات التحميل والأخطاء.
المحرر الذكي

اكتب الكود وشاهد النتيجة فوراً

جرب الآن مجاناً
قناة ديف عربي

تابع أحدث الدروس والتحديثات مباشرة على واتساب

انضم الآن