ITSkillsCenter
تطوير الويب

مقدمة في React.js: بناء واجهات مستخدم تفاعلية حديثة

4 min de lecture

لماذا React هي المكتبة الأكثر طلباً في سوق العمل؟

React.js هي مكتبة JavaScript لبناء واجهات المستخدم، طورتها Facebook (Meta). تستخدمها شركات مثل Netflix، Instagram، Airbnb، و WhatsApp Web. إذا أردت العمل كمطور واجهات أمامية، فإتقان React هو أهم مهارة يمكنك تعلمها.

ما يميز React:

  • المكونات (Components): تقسم الواجهة لقطع صغيرة قابلة لإعادة الاستخدام
  • Virtual DOM: تحديث فقط الأجزاء المتغيرة بدل إعادة رسم كل الصفحة
  • JSX: كتابة HTML داخل JavaScript بطريقة سهلة
  • Hooks: إدارة الحالة والتأثيرات الجانبية بأسلوب بسيط

إعداد بيئة العمل

# إنشاء مشروع React جديد باستخدام Vite (أسرع من CRA)
npm create vite@latest my-app -- --template react

# الدخول للمجلد وتثبيت المكتبات
cd my-app
npm install

# تشغيل خادم التطوير
npm run dev
# التطبيق يعمل على http://localhost:5173

هيكل المشروع

my-app/
├── public/
├── src/
│   ├── App.jsx          # المكون الرئيسي
│   ├── main.jsx         # نقطة البداية
│   ├── App.css
│   ├── components/      # المكونات
│   │   ├── Header.jsx
│   │   ├── ProductCard.jsx
│   │   └── Footer.jsx
│   └── hooks/           # Hooks مخصصة
│       └── useFetch.js
├── package.json
└── vite.config.js

المكونات: أساس React

كل شيء في React هو مكون (Component) — وظيفة JavaScript تُرجع JSX:

أول مكون لك

// components/Welcome.jsx
function Welcome() {
  return (
    <div className="welcome">
      <h1>مرحباً بك في React! 🚀</h1>
      <p>هذا أول مكون لك</p>
    </div>
  );
}

export default Welcome;

المكونات مع Props (الخصائص)

// components/ProductCard.jsx
function ProductCard({ name, price, image, onAddToCart }) {
  return (
    <div className="product-card">
      <img src={image} alt={name} />
      <h3>{name}</h3>
      <p className="price">{price} د.م</p>
      <button onClick={() => onAddToCart(name)}>
        أضف للسلة 🛒
      </button>
    </div>
  );
}

// الاستخدام
<ProductCard 
  name="هاتف ذكي" 
  price={2500} 
  image="/phone.jpg"
  onAddToCart={(name) => alert(`تمت إضافة ${name}`)}
/>

إدارة الحالة مع useState

import { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);
  
  return (
    <div>
      <h2>العداد: {count}</h2>
      <button onClick={() => setCount(count + 1)}>+1</button>
      <button onClick={() => setCount(count - 1)}>-1</button>
      <button onClick={() => setCount(0)}>إعادة تعيين</button>
    </div>
  );
}

// مثال أكثر تعقيداً: نموذج تسجيل
function SignupForm() {
  const [formData, setFormData] = useState({
    name: '',
    email: '',
    password: ''
  });
  const [errors, setErrors] = useState({});

  const handleChange = (e) => {
    const { name, value } = e.target;
    setFormData(prev => ({ ...prev, [name]: value }));
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    // التحقق
    const newErrors = {};
    if (!formData.name) newErrors.name = 'الاسم مطلوب';
    if (!formData.email.includes('@')) newErrors.email = 'بريد غير صحيح';
    if (formData.password.length < 6) newErrors.password = 'كلمة المرور قصيرة';
    
    if (Object.keys(newErrors).length > 0) {
      setErrors(newErrors);
      return;
    }
    
    console.log('بيانات التسجيل:', formData);
  };

  return (
    <form onSubmit={handleSubmit}>
      <input name="name" placeholder="الاسم" value={formData.name} onChange={handleChange} />
      {errors.name && <span className="error">{errors.name}</span>}
      
      <input name="email" placeholder="البريد الإلكتروني" value={formData.email} onChange={handleChange} />
      {errors.email && <span className="error">{errors.email}</span>}
      
      <input name="password" type="password" placeholder="كلمة المرور" value={formData.password} onChange={handleChange} />
      {errors.password && <span className="error">{errors.password}</span>}
      
      <button type="submit">تسجيل</button>
    </form>
  );
}

جلب البيانات مع useEffect

import { useState, useEffect } from 'react';

function ProductList() {
  const [products, setProducts] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    async function fetchProducts() {
      try {
        const response = await fetch('https://fakestoreapi.com/products');
        const data = await response.json();
        setProducts(data);
      } catch (err) {
        setError(err.message);
      } finally {
        setLoading(false);
      }
    }
    
    fetchProducts();
  }, []); // [] = يعمل مرة واحدة عند تحميل المكون

  if (loading) return <div>جاري التحميل...</div>;
  if (error) return <div>خطأ: {error}</div>;

  return (
    <div className="products-grid">
      {products.map(product => (
        <ProductCard
          key={product.id}
          name={product.title}
          price={product.price}
          image={product.image}
        />
      ))}
    </div>
  );
}

إنشاء Hook مخصص

// hooks/useFetch.js - Hook قابل لإعادة الاستخدام
import { useState, useEffect } from 'react';

function useFetch(url) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    const controller = new AbortController();
    
    async function fetchData() {
      try {
        const response = await fetch(url, { signal: controller.signal });
        const result = await response.json();
        setData(result);
      } catch (err) {
        if (err.name !== 'AbortError') setError(err.message);
      } finally {
        setLoading(false);
      }
    }
    
    fetchData();
    return () => controller.abort(); // تنظيف عند إلغاء المكون
  }, [url]);

  return { data, loading, error };
}

// الاستخدام - أبسط بكثير!
function ProductList() {
  const { data: products, loading, error } = useFetch('https://fakestoreapi.com/products');
  
  if (loading) return <div>جاري التحميل...</div>;
  if (error) return <div>خطأ: {error}</div>;
  
  return products.map(p => <ProductCard key={p.id} {...p} />);
}

عرض القوائم والتصفية

function FilterableProductList() {
  const [search, setSearch] = useState('');
  const [category, setCategory] = useState('all');
  const { data: products } = useFetch('https://fakestoreapi.com/products');

  const filtered = products?.filter(p => {
    const matchesSearch = p.title.toLowerCase().includes(search.toLowerCase());
    const matchesCategory = category === 'all' || p.category === category;
    return matchesSearch && matchesCategory;
  });

  return (
    <div>
      <input placeholder="ابحث عن منتج..." value={search} onChange={e => setSearch(e.target.value)} />
      
      <select value={category} onChange={e => setCategory(e.target.value)}>
        <option value="all">كل الأقسام</option>
        <option value="electronics">إلكترونيات</option>
        <option value="jewelery">مجوهرات</option>
        <option value="men's clothing">ملابس رجالية</option>
      </select>
      
      <div className="grid">
        {filtered?.map(p => <ProductCard key={p.id} {...p} />)}
      </div>
    </div>
  );
}

ملخص المهارات المكتسبة

  • إنشاء مشروع React باستخدام Vite
  • بناء مكونات قابلة لإعادة الاستخدام مع Props
  • إدارة الحالة باستخدام useState
  • جلب البيانات من API باستخدام useEffect
  • إنشاء Hooks مخصصة لإعادة استخدام المنطق
  • بناء نماذج مع التحقق من البيانات
  • فلترة وعرض القوائم ديناميكياً

الخطوة التالية: أضف React Router للتنقل بين الصفحات، واستخدم Context API أو Redux لإدارة الحالة العامة، ثم ابنِ مشروعاً كاملاً مثل متجر إلكتروني أو تطبيق مهام.

Besoin d'un site web ?

Confiez-nous la Création de Votre Site Web

Site vitrine, e-commerce ou application web — nous transformons votre vision en réalité digitale. Accompagnement personnalisé de A à Z.

À partir de 350.000 FCFA
Parlons de Votre Projet
Publicité