مبتدئ → تطبيقي · 10 دروس

React و Next.js — من المكوّن الأول إلى صفحة هبوط عربية

تتعلّم بناء واجهات تفاعلية بمكوّنات قابلة لإعادة الاستخدام، ثم تنتقل إلى Next.js لصفحات سريعة — وتخرج بمكوّن صفحة هبوط عربية جاهز للعرض.

كيف تدرس هذا المسار؟

  1. ثبّت Node.js وافتح مشروع React تجريبي.
  2. انسخ أمثلة المكوّنات وجرّبها في المتصفح.
  3. نفّذ المهمة — كل درس يبني صفحتك.
  4. أكمل الاختبار — التقدّم يُحفظ على جهازك.

محتوى أصلي من Mesue Learn — عملي ومناسب لسن +12 وما فوق.

1. لماذا React؟ — واجهات من قطع صغيرة

الهدف: تفهم فكرة المكوّنات ولماذا React شائع في بناء المواقع التفاعلية.

تخيّل موقعاً فيه زر «إعجاب» يتغيّر رقمه فوراً دون إعادة تحميل الصفحة كلها — هذا تفاعل.

React مكتبة JavaScript من Meta لبناء واجهات المستخدم (UI). الفكرة: تقسّم الصفحة إلى مكوّنات (Components) — كل مكوّن جزء مستقل يمكن إعادة استخدامه.

مثال: زر، بطاقة منتج، شريط تنقل — كل واحد مكوّن.

لماذا React؟
• واجهات سريعة التحديث (Virtual DOM)
• مجتمع ضخم وأدوات كثيرة
• نفس الأفكار تنتقل لـ React Native (تطبيقات موبايل)

React = مكتبة للواجهة. Next.js (لاحقاً) = إطار فوق React يضيف صفحات وتوجيهاً وSEO.

  • React يبني UI من مكوّنات قابلة لإعادة الاستخدام
  • Component = دالة أو كلاس يرجع وصفاً للواجهة
  • Virtual DOM يحدّث فقط ما تغيّر — أسرع
  • Next.js يكمّل React للمواقع الكاملة

صورة ذهنية

 [صفحة كاملة]
        |
   +----+----+
   v    v    v
 [Nav][Card][Btn]
   \    |    /
    [React]

مختبر: حدّد المكوّنات

افتح موقعاً تحبه (YouTube، Netflix، متجر) — اكتب 5 مكوّنات تتخيّلها (Header، VideoCard، SearchBar...).

مهمة عملية

اشرح لصديق في 4 جمل: ما الفرق بين React و Next.js باختصار؟

اختبر فهمك

React في المقام الأول هو...

2. المكوّنات — أول Button و Card

الهدف: تنشئ مكوّناً بسيطاً وتستدعيه داخل مكوّن آخر.

بعد إنشاء مشروع React (Vite أو Create React App):

// Button.jsx
function Button() {
return <button>اضغطني</button>;
}
export default Button;

// App.jsx
import Button from './Button';

function App() {
return (
<main>
<h1>مرحباً Mesue</h1>
<Button />
<Button />
</main>
);
}

قاعدة: اسم المكوّن يبدأ بحرف كبير (Button لا button).

مجلد src/components/ للمكوّنات المتكررة.

Mesue نصيحة: مكوّن صغير = ملف واحد — Card، Avatar، Badge.

  • المكوّن دالة ترجع JSX
  • export default لتصدير المكوّن
  • import لاستخدامه في App أو مكوّن آخر
  • اسم المكوّن PascalCase (حرف كبير)

صورة ذهنية

 App.jsx
    |
 +--+--+--+
 v  v  v  v
Nav Card Btn Footer
    \  |  /
   components/

مختبر: 3 مكوّنات

أنشئ Header و Footer و Card — اعرض Card مرتين في App بمحتوى مختلف (يدوياً حالياً).

مهمة عملية

أنشئ مشروع React (Vite) وأضف مكوّنين على الأقل يظهران في الصفحة.

اختبر فهمك

كيف تستدعي مكوّن Button داخل App؟

3. JSX — HTML داخل JavaScript

الهدف: تكتب JSX صحيحاً مع className والتعبيرات {}.

JSX = صيغة تبدو كـ HTML لكنها JavaScript.

const name = 'محمد';
return (
<section className="hero">
<h1>مرحباً {name}</h1>
<p>{2 + 2}</p>
</section>
);

قواعد مهمة:
• className بدل class (لأن class محجوزة في JS)
• htmlFor بدل for في label
• عنصر واحد جذر — أو Fragment <>...</>
• أغلق كل الوسوم: <img /> <br />

JSX ليس HTML — React يحوّله لاستدعاءات createElement.

  • JSX يخلط markup مع JavaScript
  • {}` لإدخال متغيرات وتعبيرات
  • className بدل class
  • Fragment <> يغلّف عدة عناصر دون div زائد

صورة ذهنية

 JSX في المحرر
        |
        v
   [Babel/Compiler]
        |
        v
  React.createElement

مختبر: بطاقة JSX

مكوّن ProfileCard: صورة، اسم من متغير، وسطر skills كمصفوفة .map (نص فقط حالياً).

مهمة عملية

اكتب مكوّناً يستخدم className و {} لعرض اسمك وعمرك (أو سنة الميلاد).

اختبر فهمك

في JSX، كيف تضيف class للعنصر؟

4. Props و State — بيانات للمكوّن

الهدف: تميّز بين props (من الأب) و state (داخل المكوّن).

Props = خصائص تمرّر للمكوّن — للقراءة فقط:

function Card({ title, desc }) {
return (
<article>
<h2>{title}</h2>
<p>{desc}</p>
</article>
);
}

<Card title="React" desc="مكوّنات" />

State = بيانات تتغيّر داخل المكوّن وتُعيد الرسم:

const [count, setCount] = useState(0);

عند setCount(1) React يحدّث الواجهة.

القاعدة:
• Props للتخصيص من الخارج (title، color، user)
• State للتفاعل (عداد، نموذج، فتح/إغلاق قائمة)

لا تعدّل props مباشرة — React يتجاهل ذلك.

  • Props تُمرَّر من المكوّن الأب
  • State محلي وقابل للتغيير
  • useState يُستورد من react
  • تغيير state يعيد render المكوّن

صورة ذهنية

 App (props)
    |
    v
 [Card title=...]
    |
 state داخل Card
 count, isOpen

مختبر: Card بprops

3 بطاقات دورات بعناوين مختلفة — نفس مكوّن CourseCard — props: title, hours, level.

مهمة عملية

ابنِ مكوّناً يستقبل props واعرضه 3 مرات بقيم مختلفة.

اختبر فهمك

Props في React هي...

5. useState — عدّاد ونموذج بسيط

الهدف: تستخدم Hook useState لتحديث الواجهة عند النقر أو الكتابة.

import { useState } from 'react';

function Counter() {
const [count, setCount] = useState(0);

return (
<div>
<p>العدد: {count}</p>
<button onClick={() => setCount(count + 1)}>
+1
</button>
</div>
);
}

نموذج نص:
const [text, setText] = useState('');
<input value={text} onChange={e => setText(e.target.value)} />

Hooks قواعد:
• استدعِ useState داخل جسم الدالة فقط
• لا داخل if أو حلقات
• الاسم use* = Hook (useEffect لاحقاً)

Functional update: setCount(c => c + 1) — أفضل أحياناً.

  • useState(قيمة ابتدائية) يرجع [value, setter]
  • onClick و onChange يربطان الأحداث
  • Controlled input: value + onChange
  • لا تعدّل state مباشرة — استخدم setter

صورة ذهنية

 click → setCount
        |
        v
   [state جديد]
        |
        v
   re-render UI

مختبر: عدّاد + toggle

زر يبدّل بين «مظلم/فاتح» (نص أو className على div) — state boolean isDark.

مهمة عملية

ابنِ عدّاداً بزر +1 و -1 وزر Reset — استخدم useState.

اختبر فهمك

useState يرجع...

6. القوائم والأحداث — map و key

الهدف: تعرض قائمة عناصر وتتعامل مع النقر والإرسال.

const lessons = [
{ id: 1, title: 'JSX' },
{ id: 2, title: 'Props' },
];

<ul>
{lessons.map(lesson => (
<li key={lesson.id}>{lesson.title}</li>
))}
</ul>

key = معرّف فريد — يساعد React على تحديث القائمة بكفاءة.

أحداث:
<button onClick={handleClick}>نقر</button>
<form onSubmit={handleSubmit}>

function handleSubmit(e) {
e.preventDefault(); // يمنع إعادة تحميل الصفحة
// منطق الإرسال
}

Mesue: لا تستخدم index كـ key إن القائمة تتغيّر (حذف/إضافة).

  • map يحوّل مصفوفة إلى JSX
  • key فريد لكل عنصر في القائمة
  • e.preventDefault() في النماذج
  • مرّر دالة للحدث — onClick={fn} لا onClick={fn()}

صورة ذهنية

 [array]
    |
  .map()
    |
 v  v  v
 li li li
 key key key

مختبر: قائمة مهام

state مصفوفة tasks — input + زر «أضف» — onSubmit يضيف عنصراً — map يعرض القائمة.

مهمة عملية

اعرض 5 عناصر من مصفوفة بـ map — أضف onClick يطبع العنصر في console.

اختبر فهمك

لماذا key في قائمة React؟

7. fetch و API — بيانات من الإنترنت

الهدف: تجلب JSON من API وتعرضه مع loading و error.

import { useState, useEffect } from 'react';

function UserList() {
const [users, setUsers] = useState([]);
const [loading, setLoading] = useState(true);

useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/users')
.then(res => res.json())
.then(data => {
setUsers(data);
setLoading(false);
})
.catch(err => {
console.error(err);
setLoading(false);
});
}, []); // [] = مرة واحدة عند التحميل

if (loading) return <p>جاري التحميل...</p>;

return (
<ul>
{users.map(u => <li key={u.id}>{u.name}</li>)}
</ul>
);
}

async/await بديل:
const res = await fetch(url);
const data = await res.json();

  • fetch يرجع Promise
  • useEffect لل副作用 عند mount
  • loading و error تجربة مستخدم أفضل
  • [] dependency = تشغيل مرة واحدة

صورة ذهنية

 useEffect
     |
  fetch(url)
     |
     v
  JSON → setState
     |
     v
   UI update

مختبر: posts

jsonplaceholder /posts — اعرض 10 عناوين — حالة «جاري التحميل» و «فشل الاتصال».

مهمة عملية

اجلب بيانات من API عام واعرضها في قائمة — مع رسالة تحميل.

اختبر فهمك

useEffect مع [] فارغة يعني...

8. Next.js — React جاهز للمواقع

الهدف: تفهم لماذا Next.js وكيف تنشئ مشروعاً أولاً.

React وحده = واجهة في المتصفح (SPA غالباً).
Next.js = إطار فوق React يضيف:
• صفحات ملفّية (pages/ أو app/)
• توجيه (Routing) تلقائي
• Server Components (إصدارات حديثة)
• SEO وتحميل أسرع

إنشاء مشروع:
npx create-next-app@latest mesue-next

اختر: TypeScript (اختياري)، App Router، Tailwind (اختياري).

cd mesue-next && npm run dev

افتح http://localhost:3000

هيكل App Router:
app/page.jsx = الصفحة الرئيسية
app/layout.jsx = غلاف مشترك (html، nav)

  • Next.js يبني على React
  • create-next-app للبداية السريعة
  • npm run dev للتطوير المحلي
  • app/ أو pages/ حسب إصدار Router

صورة ذهنية

 [Next.js]
     |
 +---+---+---+
 v   v   v   v
Route SSR SEO Files

مختبر: أول تشغيل

عدّل app/page.jsx — عنوان عربي «مرحباً Mesue» — احفظ وشاهد Hot Reload.

مهمة عملية

أنشئ مشروع Next.js وشغّله محلياً — لقطة شاشة للصفحة الافتراضية.

اختبر فهمك

Next.js يضيف لـ React أساساً...

9. التوجيه — صفحات وروابط

الهدف: تنشئ صفحات متعددة وتربطها بـ Link.

App Router (Next.js 13+):

app/page.jsx → /
app/about/page.jsx → /about
app/learn/page.jsx → /learn

import Link from 'next/link';

<nav>
<Link href="/">الرئيسية</Link>
<Link href="/about">من نحن</Link>
<Link href="/learn">تعلّم</Link>
</nav>

استخدم Link بدل <a> للتنقل الداخلي — أسرع دون إعادة تحميل كاملة.

layout.jsx يغلّف كل الصفحات:
export default function Layout({ children }) {
return (
<>
<header>...</header>
{children}
<footer>...</footer>
</>
);
}

  • مجلد + page.jsx = مسار URL
  • Link from next/link للتنقل
  • layout.jsx للعناصر المشتركة
  • href=\"/path\" بدون .jsx في الرابط

صورة ذهنية

 layout.jsx
      |
 +----+----+
 v         v
 /      /about
page    page

مختبر: 3 صفحات

أنشئ /about و /courses — Nav في layout — كل صفحة عنوان H1 عربي مختلف.

مهمة عملية

أضف صفحتين جديدتين وشريط تنقل يعمل بينها.

اختبر فهمك

في App Router، مسار /about يُعرّف بـ...

10. المشروع النهائي — صفحة هبوط عربية

الهدف: تسلّم مكوّن صفحة هبوط عربية كاملة في Next.js جاهزة للعرض.

المطلوب: مشروع Next.js (mesue-landing أو مشابه)

صفحة رئيسية عربية (dir="rtl") تتضمن:
• Hero: عنوان + وصف + زر CTA («ابدأ التعلّم»)
• قسم 3 بطاقات (ميزات أو دورات)
• قسم تواصل أو footer
• Nav بـ Link
• useState لزر تفاعلي (مثلاً toggle FAQ أو عدّاد)
• (اختياري) fetch لعرض اقتباس من API

معيار النجاح:
✓ npm run dev يعمل دون أخطاء
✓ نص عربي واضح واتجاه RTL
✓ 3+ مكوّنات منفصلة (Hero، FeatureCard، Footer)
✓ README: كيف تشغّل المشروع
✓ commit أخير: «Landing page ready»

  • قسّم الصفحة لمكوّنات نظيفة
  • RTL وخط عربي يحسّنان المظهر
  • تفاعل واحد على الأقل (useState)
  • README يشرح npm install && npm run dev

صورة ذهنية

 Nav
  |
 Hero → Features → CTA
  |
 Footer
  |
 [GitHub / Vercel]

مختبر: العرض النهائي

اعرض الصفحة على صديق — هل فهم المحتوى خلال 30 ثانية؟ هل الزر التفاعلي يعمل؟

مهمة عملية

انشر صفحة الهبوط (GitHub + Vercel اختياري) + README عربي — شارك الرابط في Mesue Learn إن رغبت.

اختبر فهمك

أفضل ممارسة لمشروع Next.js للعرض؟

صفحة هبوط عربية جاهزة

انشر مشروعك على Vercel أو تابع مسار السحابة لاستضافة ذاتية.