إنشاء النماذج (Forms) في React: دليل شامل
تُعتبر النماذج (Forms) أحد العناصر الأساسية في تطوير واجهات المستخدم، إذ تتيح للمستخدمين إدخال البيانات والتفاعل مع التطبيقات بطريقة ديناميكية. وعند استخدام مكتبة React لبناء الواجهات، تصبح إدارة النماذج أكثر تعقيدًا وتطلبًا من حيث التصميم وتنظيم الحالة (state) والتحقق من صحة البيانات. هذا المقال يعرض بشكل موسّع كيفية إنشاء النماذج في React بأسلوب علمي، مع توضيح التقنيات المختلفة المستخدمة، وأفضل الممارسات لتطوير نماذج فعالة وقابلة للصيانة في تطبيقات الويب الحديثة.
مفهوم النماذج في React
النموذج في React لا يختلف كثيرًا من حيث البنية عن نماذج HTML التقليدية، لكنه يدار بطريقة مختلفة تمامًا فيما يتعلق بربط البيانات والتحكم في الحالة. في React، يتم استخدام ما يُعرف بـ النماذج المتحكمة (Controlled Forms) والنماذج غير المتحكمة (Uncontrolled Forms)، ويُفضل غالبًا استخدام النماذج المتحكمة لأن ذلك يتيح للمطور التحكم الكامل في مدخلات النموذج من خلال الحالة والمكونات.
النماذج المتحكمة (Controlled Forms)
النموذج المتحكم هو النموذج الذي يتم فيه ربط قيمة كل حقل إدخال (input) بمتغير في حالة المكون (useState). كل مرة يُحدث المستخدم تغييرًا في الحقل، يتم تحديث الحالة عبر معالج الحدث (onChange).
مثال أساسي:
jsximport React, { useState } from "react";
function ContactForm() {
const [name, setName] = useState("");
const [email, setEmail] = useState("");
const handleSubmit = (event) => {
event.preventDefault();
console.log("Submitted Data:", { name, email });
};
return (
<form onSubmit={handleSubmit}>
<label>الاسم:label>
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
/>
<label>البريد الإلكتروني:label>
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
<button type="submit">إرسالbutton>
form>
);
}
النماذج غير المتحكمة (Uncontrolled Forms)
في النماذج غير المتحكمة، يتم استخدام مرجع (Ref) للوصول إلى القيمة المدخلة في الحقول بدلًا من استخدام الحالة. يتم ذلك عبر استخدام useRef.
مثال:
jsximport React, { useRef } from "react";
function SimpleForm() {
const nameRef = useRef();
const emailRef = useRef();
const handleSubmit = (event) => {
event.preventDefault();
const name = nameRef.current.value;
const email = emailRef.current.value;
console.log("Submitted Data:", { name, email });
};
return (
<form onSubmit={handleSubmit}>
<label>الاسم:label>
<input type="text" ref={nameRef} />
<label>البريد الإلكتروني:label>
<input type="email" ref={emailRef} />
<button type="submit">إرسالbutton>
form>
);
}
المقارنة بين النماذج المتحكمة وغير المتحكمة
| الخاصية | النماذج المتحكمة | النماذج غير المتحكمة |
|---|---|---|
| التحكم بالحالة | كامل عبر useState |
عبر الوصول المباشر للحقل باستخدام ref |
| الأداء | أبطأ في النماذج الكبيرة | أسرع لعدم إعادة التصيير |
| سهولة التحقق من البيانات | أسهل لأنها موجودة في الحالة مباشرة | أكثر تعقيدًا |
| الاستخدام | شائع في معظم التطبيقات | مفيد في الحالات البسيطة |
التحقق من صحة البيانات (Validation)
للتحقق من صحة البيانات في النماذج، يمكن استخدام أساليب متعددة. أبسطها التحقق اليدوي داخل المعالج handleSubmit، ولكن في التطبيقات المتقدمة يوصى باستخدام مكتبات مثل Formik و Yup.
مثال يدوي:
jsxconst handleSubmit = (event) => {
event.preventDefault();
if (!email.includes("@")) {
alert("يرجى إدخال بريد إلكتروني صحيح");
return;
}
console.log("تم الإرسال بنجاح");
};
استخدام Formik لإدارة النماذج
Formik هي مكتبة شهيرة في React تُسهِّل إدارة النماذج والتحقق من صحة المدخلات.
مثال باستخدام Formik و Yup:
jsximport { useFormik } from "formik";
import * as Yup from "yup";
function SignupForm() {
const formik = useFormik({
initialValues: {
name: "",
email: "",
},
validationSchema: Yup.object({
name: Yup.string().required("الاسم مطلوب"),
email: Yup.string().email("البريد غير صحيح").required("البريد مطلوب"),
}),
onSubmit: (values) => {
console.log("تم الإرسال:", values);
},
});
return (
<form onSubmit={formik.handleSubmit}>
<input
name="name"
value={formik.values.name}
onChange={formik.handleChange}
/>
{formik.errors.name && <div>{formik.errors.name}div>}
<input
name="email"
value={formik.values.email}
onChange={formik.handleChange}
/>
{formik.errors.email && <div>{formik.errors.email}div>}
<button type="submit">تسجيلbutton>
form>
);
}
التعامل مع الحقول الديناميكية
في بعض الحالات، تحتاج النماذج إلى إضافة أو إزالة الحقول ديناميكيًا مثل إضافة أكثر من رقم هاتف أو بريد إلكتروني.
مثال على ذلك:
jsximport React, { useState } from "react";
function DynamicForm() {
const [emails, setEmails] = useState([""]);
const handleChange = (index, event) => {
const newEmails = [...emails];
newEmails[index] = event.target.value;
setEmails(newEmails);
};
const addEmailField = () => {
setEmails([...emails, ""]);
};
return (
<form>
{emails.map((email, index) => (
<input
key={index}
type="email"
value={email}
onChange={(e) => handleChange(index, e)}
/>
))}
<button type="button" onClick={addEmailField}>إضافة بريدbutton>
form>
);
}
معالجة الملفات داخل النموذج
تعامل React مع تحميل الملفات يتم من خلال input[type="file"] وغالبًا باستخدام المرجع ref.
jsxfunction FileUpload() {
const fileRef = useRef();
const handleUpload = () => {
const file = fileRef.current.files[0];
console.log("تم تحميل الملف:", file.name);
};
return (
<div>
<input type="file" ref={fileRef} />
<button onClick={handleUpload}>رفع الملفbutton>
div>
);
}
أفضل الممارسات عند تصميم النماذج في React
-
تنظيم الحالة: استخدم
useReducerفي النماذج الكبيرة لتجنب كثرة استخدامuseState. -
إعادة الاستخدام: قم بتجميع الحقول المتكررة في مكونات مستقلة.
-
الفصل بين المنطق والعرض: استخدم مبدأ “التركيب” للفصل بين واجهة النموذج ومعالجة البيانات.
-
التحقق الآني: قدم ملاحظات فورية للمستخدم بمجرد إدخال البيانات لتجربة استخدام أفضل.
-
تحسين الأداء: تجنب التصيير غير الضروري باستخدام
React.memoأوuseCallback.
استخدام مكتبات إضافية لتوسيع الوظائف
مكتبة React Hook Form
واحدة من أكثر المكتبات خفة وسرعة في التعامل مع النماذج. تعتمد على الأداء العالي باستخدام المرجع بدلًا من التحديث المستمر للحالة.
مثال باستخدام React Hook Form:
jsximport { useForm } from "react-hook-form";
function RHFForm() {
const { register, handleSubmit, errors } = useForm();
const onSubmit = (data) => {
console.log(data);
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input name="name" ref={register({ required: true })} />
{errors.name && <span>الاسم مطلوبspan>}
<input name="email" ref={register({ required: true })} />
{errors.email && <span>البريد مطلوبspan>}
<button type="submit">إرسالbutton>
form>
);
}
الخلاصة التقنية
إن إنشاء النماذج في React يتطلب فهمًا جيدًا لكيفية إدارة الحالة والتفاعل مع DOM بطريقة غير مباشرة. يُوصى باستخدام النماذج المتحكمة في المشاريع التي تحتاج إلى تحقق دقيق من البيانات، بينما يمكن استخدام النماذج غير المتحكمة في حالات بسيطة. كما يُفضل الاعتماد على مكتبات مثل Formik أو React Hook Form لتوفير الوقت والجهد وتقليل التعقيد البرمجي في النماذج الكبيرة.
جدول يوضح الفروقات بين أدوات إنشاء النماذج في React
| الميزة | React فقط | Formik | React Hook Form |
|---|---|---|---|
| سهولة الاستخدام | متوسطة | عالية | عالية |
| الأداء | جيد | أبطأ قليلاً | ممتاز |
| دعم التحقق من الصحة | يدوي | نعم (مع Yup) | نعم |
| مرونة التخصيص | عالي | عالي | متوسط |
| حجم الحزمة | صغير | متوسط | صغير جدًا |
المراجع:

