البرمجة

إنشاء النماذج في React

إنشاء النماذج (Forms) في React: دليل شامل

تُعتبر النماذج (Forms) أحد العناصر الأساسية في تطوير واجهات المستخدم، إذ تتيح للمستخدمين إدخال البيانات والتفاعل مع التطبيقات بطريقة ديناميكية. وعند استخدام مكتبة React لبناء الواجهات، تصبح إدارة النماذج أكثر تعقيدًا وتطلبًا من حيث التصميم وتنظيم الحالة (state) والتحقق من صحة البيانات. هذا المقال يعرض بشكل موسّع كيفية إنشاء النماذج في React بأسلوب علمي، مع توضيح التقنيات المختلفة المستخدمة، وأفضل الممارسات لتطوير نماذج فعالة وقابلة للصيانة في تطبيقات الويب الحديثة.


مفهوم النماذج في React

النموذج في React لا يختلف كثيرًا من حيث البنية عن نماذج HTML التقليدية، لكنه يدار بطريقة مختلفة تمامًا فيما يتعلق بربط البيانات والتحكم في الحالة. في React، يتم استخدام ما يُعرف بـ النماذج المتحكمة (Controlled Forms) والنماذج غير المتحكمة (Uncontrolled Forms)، ويُفضل غالبًا استخدام النماذج المتحكمة لأن ذلك يتيح للمطور التحكم الكامل في مدخلات النموذج من خلال الحالة والمكونات.


النماذج المتحكمة (Controlled Forms)

النموذج المتحكم هو النموذج الذي يتم فيه ربط قيمة كل حقل إدخال (input) بمتغير في حالة المكون (useState). كل مرة يُحدث المستخدم تغييرًا في الحقل، يتم تحديث الحالة عبر معالج الحدث (onChange).

مثال أساسي:

jsx
import 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.

مثال:

jsx
import 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.

مثال يدوي:

jsx
const handleSubmit = (event) => { event.preventDefault(); if (!email.includes("@")) { alert("يرجى إدخال بريد إلكتروني صحيح"); return; } console.log("تم الإرسال بنجاح"); };

استخدام Formik لإدارة النماذج

Formik هي مكتبة شهيرة في React تُسهِّل إدارة النماذج والتحقق من صحة المدخلات.

مثال باستخدام Formik و Yup:

jsx
import { 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> ); }

التعامل مع الحقول الديناميكية

في بعض الحالات، تحتاج النماذج إلى إضافة أو إزالة الحقول ديناميكيًا مثل إضافة أكثر من رقم هاتف أو بريد إلكتروني.

مثال على ذلك:

jsx
import 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.

jsx
function 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:

jsx
import { 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) نعم
مرونة التخصيص عالي عالي متوسط
حجم الحزمة صغير متوسط صغير جدًا

المراجع:

  1. https://reactjs.org/docs/forms.html

  2. https://formik.org/docs/overview