React

أول تطبيق React لك — من JSX إلى المكونات 2026

📅 2026-10-11⏱ 8 دقائق قراءة
في المقال السابق، قمنا بتثبيت React باستخدام Vite وتأكدنا من أن بيئة العمل جاهزة. الآن حان الوقت لكتابة **أول تطبيق React** لك وفهم الأساسيات. في هذا الدليل العملي، سنأخذك خطوة بخطوة من JSX إلى المكونات، مع تمارين وحلول. ## ما هو JSX؟ **JSX** هو اختصار لـ **JavaScript XML**. هو **صيغة** تسمح لك بكتابة HTML داخل JavaScript. **مثال:** ```tsx const element = <h1>مرحباً بالعالم!</h1>; ``` **هذا ليس HTML، وليس JavaScript — إنه JSX!** ### كيف يعمل JSX؟ JSX **يُحوَّل** إلى JavaScript عادي بواسطة Babel أو Vite: ```tsx // ما تكتبه (JSX): const element = <h1>مرحباً!</h1>; // ما يُحوَّل إليه (JavaScript): const element = React.createElement("h1", null, "مرحباً!"); ``` **الفائدة:** JSX **أسهل للقراءة والكتابة** من `React.createElement`. ## لماذا JSX؟ - **مألوف:** يشبه HTML. - **قوي:** يمكن تضمين تعبيرات JavaScript. - **آمن:** يمنع هجمات XSS تلقائياً. - **واضح:** يوضح بنية الواجهة. ## قواعد JSX الأساسية ### 1. إرجاع عنصر واحد فقط **❌ خطأ:** ```tsx return ( <h1>عنوان</h1> <p>فقرة</p> ); ``` **✅ صحيح:** ```tsx return ( <div> <h1>عنوان</h1> <p>فقرة</p> </div> ); ``` **أو باستخدام Fragment:** ```tsx return ( <> <h1>عنوان</h1> <p>فقرة</p> </> ); ``` ### 2. إغلاق جميع الوسوم **❌ خطأ:** ```tsx <img src="logo.png"> <br> <input type="text"> ``` **✅ صحيح:** ```tsx <img src="logo.png" /> <br /> <input type="text" /> ``` ### 3. استخدام `className` بدلاً من `class` **❌ خطأ:** ```tsx <div class="container">...</div> ``` **✅ صحيح:** ```tsx <div className="container">...</div> ``` **السبب:** `class` كلمة محجوزة في JavaScript. ### 4. استخدام `htmlFor` بدلاً من `for` **❌ خطأ:** ```tsx <label for="name">الاسم:</label> ``` **✅ صحيح:** ```tsx <label htmlFor="name">الاسم:</label> ``` ### 5. تضمين تعبيرات JavaScript بـ `{}` ```tsx const name = "أحمد"; const age = 25; return ( <div> <h1>مرحباً {name}!</h1> <p>عمرك {age} سنة</p> <p>بعد 5 سنوات: {age + 5} سنة</p> </div> ); ``` ### 6. الشروط داخل JSX ```tsx const isLoggedIn = true; return ( <div> {isLoggedIn ? <p>مرحباً بك!</p> : <p>سجّل الدخول</p>} </div> ); ``` ### 7. القوائم داخل JSX ```tsx const fruits = ["تفاح", "موز", "برتقال"]; return ( <ul> {fruits.map((fruit) => ( <li key={fruit}>{fruit}</li> ))} </ul> ); ``` **⚠️ مهم:** كل عنصر في القائمة يحتاج **`key` فريد**. ## أول مكون React **المكوّن (Component)** هو **دالة JavaScript** تُرجع JSX. ### 1. مكون بسيط **أنشئ ملف `src/Hello.tsx`:** ```tsx function Hello() { return <h1>مرحباً من React!</h1>; } export default Hello; ``` ### 2. استخدام المكون في `App.tsx` **افتح `src/App.tsx`:** ```tsx import Hello from "./Hello"; function App() { return ( <div> <Hello /> <Hello /> <Hello /> </div> ); } export default App; ``` **النتيجة:** ستظهر "مرحباً من React!" **3 مرات**. **🎉 مبروك! لقد أنشأت أول مكون React!** ## المكونات مع Props **Props** هي **بيانات** تُمرر للمكون. ### 1. تعريف Props ```tsx interface GreetingProps { name: string; age: number; } function Greeting({ name, age }: GreetingProps) { return ( <div> <h2>مرحباً {name}!</h2> <p>عمرك {age} سنة</p> </div> ); } export default Greeting; ``` ### 2. استخدام Props ```tsx import Greeting from "./Greeting"; function App() { return ( <div> <Greeting name="أحمد" age={25} /> <Greeting name="محمد" age={30} /> <Greeting name="علي" age={22} /> </div> ); } export default App; ``` **النتيجة:** 3 بطاقات ترحيب بأسماء وأعمار مختلفة. ### 3. Props مع قيم افتراضية ```tsx interface ButtonProps { text?: string; color?: string; } function Button({ text = "اضغط", color = "blue" }: ButtonProps) { return ( <button style={{ backgroundColor: color }}> {text} </button> ); } ``` ## إنشاء تطبيق "بطاقة شخصية" دعنا نبني تطبيقاً يعرض بطاقات شخصية. ### 1. مكون `Card.tsx` ```tsx interface CardProps { name: string; role: string; image: string; } function Card({ name, role, image }: CardProps) { return ( <div className="card"> <img src={image} alt={name} /> <h3>{name}</h3> <p>{role}</p> </div> ); } export default Card; ``` ### 2. استخدام `Card` في `App.tsx` ```tsx import Card from "./Card"; function App() { const people = [ { name: "أحمد", role: "مطور ويب", image: "https://i.pravatar.cc/150?img=1" }, { name: "محمد", role: "مصمم UI", image: "https://i.pravatar.cc/150?img=2" }, { name: "علي", role: "مهندس بيانات", image: "https://i.pravatar.cc/150?img=3" }, ]; return ( <div className="app"> <h1>فريقنا</h1> <div className="cards"> {people.map((person) => ( <Card key={person.name} name={person.name} role={person.role} image={person.image} /> ))} </div> </div> ); } export default App; ``` ### 3. تصميم `src/index.css` ```css * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Segoe UI', Tahoma, sans-serif; background: #f1f5f9; padding: 40px; direction: rtl; } .app h1 { text-align: center; margin-bottom: 40px; color: #1e293b; } .cards { display: flex; gap: 20px; justify-content: center; flex-wrap: wrap; } .card { background: white; padding: 24px; border-radius: 16px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); text-align: center; width: 200px; } .card img { width: 100px; height: 100px; border-radius: 50%; margin-bottom: 16px; } .card h3 { color: #1e293b; margin-bottom: 8px; } .card p { color: #64748b; font-size: 14px; } ``` **🎉 مبروك! لديك تطبيق React كامل!** ## التعبيرات الشرطية في JSX ### 1. `if` خارج JSX ```tsx function Greeting({ isLoggedIn }: { isLoggedIn: boolean }) { if (isLoggedIn) { return <h1>مرحباً بك!</h1>; } return <h1>سجّل الدخول</h1>; } ``` ### 2. Ternary Operator داخل JSX ```tsx function Greeting({ isLoggedIn }: { isLoggedIn: boolean }) { return ( <h1>{isLoggedIn ? "مرحباً بك!" : "سجّل الدخول"}</h1> ); } ``` ### 3. `&&` للعرض الشرطي ```tsx function Inbox({ messages }: { messages: string[] }) { return ( <div> <h1>صندوق الوارد</h1> {messages.length > 0 && ( <p>لديك {messages.length} رسالة</p> )} {messages.length === 0 && <p>لا توجد رسائل</p>} </div> ); } ``` ## التعبيرات في JSX ### 1. استدعاء الدوال ```tsx function formatName(user: { firstName: string; lastName: string }) { return `${user.firstName} ${user.lastName}`; } const user = { firstName: "أحمد", lastName: "محمد" }; return <h1>مرحباً {formatName(user)}</h1>; ``` ### 2. العمليات الحسابية ```tsx const price = 100; const tax = 0.15; return ( <div> <p>السعر: {price}</p> <p>الضريبة: {price * tax}</p> <p>الإجمالي: {price + price * tax}</p> </div> ); ``` ### 3. استخدام `style` ككائن ```tsx const styles = { color: "red", fontSize: "24px", fontWeight: "bold", }; return <h1 style={styles}>عنوان ملوّن</h1>; ``` **⚠️ ملاحظة:** أسماء خصائص CSS في React تستخدم **camelCase**: - `font-size` → `fontSize` - `background-color` → `backgroundColor` - `text-align` → `textAlign` ## تمارين عملية ### تمرين 1: مكون بسيط أنشئ مكوناً `Welcome` يعرض "مرحباً بالعالم!". **الحل:** ```tsx function Welcome() { return <h1>مرحباً بالعالم!</h1>; } export default Welcome; ``` ### تمرين 2: مكون مع Props أنشئ مكوناً `User` يأخذ `name` و `age` و `city`. **الحل:** ```tsx interface UserProps { name: string; age: number; city: string; } function User({ name, age, city }: UserProps) { return ( <div> <h3>{name}</h3> <p>العمر: {age}</p> <p>المدينة: {city}</p> </div> ); } export default User; ``` ### تمرين 3: قائمة أنشئ مصفوفة أرقام واعرضها في قائمة. **الحل:** ```tsx function NumberList() { const numbers = [1, 2, 3, 4, 5]; return ( <ul> {numbers.map((n) => ( <li key={n}>{n}</li> ))} </ul> ); } ``` ### تمرين 4: شرط أنشئ مكوناً يعرض "صيف" إذا كان الشهر 6-8، وإلا يعرض "شتاء". **الحل:** ```tsx function Season({ month }: { month: number }) { const isSummer = month >= 6 && month <= 8; return <h1>{isSummer ? "☀️ صيف" : "❄️ شتاء"}</h1>; } ``` ### تمرين 5: بطاقة منتج أنشئ مكون `Product` يأخذ `name`, `price`, `image`. **الحل:** ```tsx interface ProductProps { name: string; price: number; image: string; } function Product({ name, price, image }: ProductProps) { return ( <div className="product"> <img src={image} alt={name} /> <h3>{name}</h3> <p>{price} $</p> </div> ); } ``` ### تمرين 6: عداد بسيط أنشئ مكوناً يعرض عدد النقرات (بدون state، فقط عرض). **الحل:** ```tsx function StaticCounter() { const count = 5; return <p>العدد: {count}</p>; } ``` **⚠️ ملاحظة:** العداد الحقيقي يحتاج `useState` — سنتعلمه في المقال الرابع. ## حل المشاكل الشائعة ### 🔴 المشكلة 1: `Adjacent JSX elements must be wrapped` **السبب:** إرجاع عدة عناصر بدون غلاف. **الحل:** استخدم `<div>` أو `<>...</>`: ```tsx return ( <> <h1>عنوان</h1> <p>فقرة</p> </> ); ``` ### 🔴 المشكلة 2: `className` بدلاً من `class` **السبب:** استخدام `class` في JSX. **الحل:** استخدم `className`. ### 🔴 المشكلة 3: `key` مفقود في القائمة **السبب:** عدم وجود `key` فريد. **الحل:** أضف `key={item.id}` أو `key={index}`. ### 🔴 المشكلة 4: `Cannot read property of undefined` **السبب:** الوصول لخاصية غير موجودة. **الحل:** استخدم `?.` (Optional Chaining): ```tsx <p>{user?.name}</p> ``` ### 🔴 المشكلة 5: `Objects are not valid as a React child` **السبب:** محاولة عرض كائن مباشرة. **الحل:** اعرض خاصية من الكائن: ```tsx <p>{user.name}</p> {/* ✅ */} <p>{user}</p> {/* ❌ */} ``` ## جدول قواعد JSX <table> <thead> <tr> <th>القاعدة</th> <th>❌ خطأ</th> <th>✅ صحيح</th> </tr> </thead> <tbody> <tr> <td>عنصر واحد</td> <td><code>&lt;h1&gt;...&lt;/h1&gt;&lt;p&gt;...&lt;/p&gt;</code></td> <td><code>&lt;div&gt;...&lt;/div&gt;</code></td> </tr> <tr> <td>إغلاق الوسوم</td> <td><code>&lt;img&gt;</code></td> <td><code>&lt;img /&gt;</code></td> </tr> <tr> <td>Class</td> <td><code>class="..."</code></td> <td><code>className="..."</code></td> </tr> <tr> <td>For</td> <td><code>for="..."</code></td> <td><code>htmlFor="..."</code></td> </tr> <tr> <td>تعبيرات</td> <td><code>name</code></td> <td><code>{name}</code></td> </tr> </tbody> </table> ## قائمة تحقق نهائية <table> <thead> <tr> <th>المهمة</th> <th>الحالة</th> </tr> </thead> <tbody> <tr> <td>فهم JSX وقواعده</td> <td>⬜</td> </tr> <tr> <td>إنشاء أول مكون React</td> <td>⬜</td> </tr> <tr> <td>استخدام Props</td> <td>⬜</td> </tr> <tr> <td>عرض القوائم</td> <td>⬜</td> </tr> <tr> <td>الشروط في JSX</td> <td>⬜</td> </tr> <tr> <td>بناء تطبيق البطاقات</td> <td>⬜</td> </tr> <tr> <td>حل التمارين الستة</td> <td>⬜</td> </tr> </tbody> </table> ## ماذا بعد هذا المقال؟ الآن بعد أن فهمت JSX والمكونات، أنت جاهز للمقال التالي: 1. **المكونات المتقدمة** — تعمق في المكونات. 2. **State** — إدارة البيانات المتغيرة. 3. **الأحداث** — التعامل مع تفاعل المستخدم. ## الخلاصة في هذا المقال، تعلمت: - ✅ ما هو JSX وقواعده. - ✅ إنشاء أول مكون React. - ✅ استخدام Props لتمرير البيانات. - ✅ عرض القوائم بـ `map`. - ✅ الشروط في JSX. - ✅ التعبيرات في JSX. - ✅ حل 6 تمارين عملية. **تذكر:** JSX هو قلب React. أتقن قواعده، وستصبح مبرمج React محترف. **هل بنيت أول تطبيق React؟ شاركنا في التعليقات!**