React: إعداد البيئة و JSX

آخر تحديث: 2026-08-26

كتابة كود React تشبه تجديد منزل — Vite هي فريق البناء (فهي تساعدك في إعداد السقالات وخادم التطوير)، وJSX هي المخطط (وهي صيغة لكتابة HTML داخل JavaScript). في هذا الدرس، ستقوم بإنشاء أول مشروع React خاص بك من الصفر.


1. ما ستتعلمه



2. قصة حقيقية لمطور مبتدئ

(1) المشكلة: استغرق إعداد البيئة يومًا كاملاً

لقد تعلم بوب لغة جافا سكريبت مؤخرًا ويرغب في تجربة React. بحث على الإنترنت عن دروس تعليمية، فوجد أن البعض أوصى باستخدام Create React App، بينما أوصى آخرون باستخدام Vite، وأوصى آخرون باستخدام Next.js. فاختار CRA عشوائيًا وبدأ عملية التثبيت:

BASH
npx create-react-app my-app

النتائج:

شعر بوب بالإحباط: «لم أبدأ حتى في كتابة الكود، وقد أهدرت ساعة بالفعل».

(2) الحل باستخدام Vite و React

إنشاء نفس المشروع باستخدام Vite:

BASH
npm create vite@latest my-app -- --template react-ts
cd my-app
npm install
npm run dev
المقارنة CRA Vite
مدة التثبيت ~8 دقائق ~30 ثانية
وقت بدء التشغيل ~30 ثانية < 1 ثانية
استبدال الوحدة الساخنة (HMR) 2–3 ثوانٍ <50 مللي ثانية
وقت البناء ~60 ثانية ~10 ثوانٍ
حجم node_modules ~200 ميغابايت ~80 ميغابايت

المزايا: لم يستغرق الأمر من بوب سوى 3 دقائق من لحظة التثبيت حتى ظهور عبارة "Hello World"، كما أن التحديثات الفورية سريعة للغاية لدرجة أنك بالكاد تلاحظ فترة الانتظار.



3. القواعد الأساسية لـ JSX

JSX هي اختصار لـ JavaScript XML. وهي ليست HTML، بل هي امتداد لصيغة لغة JavaScript. ويتم ترجمة كل تعبير JSX في النهاية إلى استدعاء React.createElement().

100%
graph LR
    A[JSX Code] --> B[Babel Compilation]
    B --> C[React.createElement]
    C --> D[Virtual DOM Object]
    D --> E[True DOM]
    
    style A fill:#61dafb,color:#000
    style C fill:#ff6b6b,color:#fff

(1) قاعدة العنصر الواحد

يجب أن تحتوي تعبيرات JSX على عنصر جذر. ولا يمكنها إرجاع عنصرين متجاورين.

JSX
// ❌ Error:No root element
return (
  <h1>Title</h1>
  <p>Paragraph</p>
)

// ✅ Correct:Use one <div> Package
return (
  <div>
    <h1>Title</h1>
    <p>Paragraph</p>
  </div>
)

// ✅ You can also use React Fragment(<></>),Does not incur additional DOM
return (
  <>
    <h1>Title</h1>
    <p>Paragraph</p>
  </>
)
▶ جرّب الكود

(2) تضمين تعبيرات جافا سكريبت في JSX

استخدم الأقواس {} لتضمين أي تعبير JavaScript:

JSX
const name = 'Alice'
const age = 28
const colors = ['red', 'green', 'blue']

// Variable
<h1>Hello, {name}!</h1>

// Expression Evaluation
<p>Next year {age + 1} years old</p>

// Ternary Operator
<span>{age >= 18 ? 'Adulthood' : 'Minor'}</span>

// Function Call
<p>Today's Date:{new Date().toLocaleDateString()}</p>

// Array Length
<p>Total {colors.length} A Color</p>
▶ جرّب الكود

(3) جدول مرجعي سريع: الاختلافات بين JSX و HTML

ميزة HTML JSX
اسم الفئة class="box" className="box" (كلمة "class" هي كلمة محجوزة في لغة جافا سكريبت)
سمة العلامة for="input" htmlFor="input" (لأنها كلمة محجوزة في جافا سكريبت)
الأنماط المضمنة style="color:red" style={{ color: 'red' }} (صيغة الكائن)
خاصية منطقية disabled disabled={true} أو disabled
العلامات ذاتية الإغلاق <br> <img> يجب إغلاقها: <br /> <img />
ملاحظة <!-- comment --> {/* comment */}
ربط الأحداث onclick="handle()" onClick={handle}
اسم خاصية CSS font-size (واصلة) fontSize (camelCase)

▶ مثال: مقارنة بين JSX و HTML

JSX
// ============================================
// Example:The Same Card,HTML vs JSX Comparison of Writing Styles
// ============================================

// ---- HTML Writing Style ----
<div class="card" style="background-color: #f0f0f0; padding: 20px;">
  <!-- TODO: replace with actual user avatar image -->
  <img src="https://i.pravatar.cc/80" alt="Avatar" class="avatar">
  <label for="name">Name:</label>
  <input type="text" id="name" disabled>
  <!-- This is a comment. -->
  <button onclick="handleClick()">Click</button>
</div>

// ---- JSX Writing Style ----
<div className="card" style={{ backgroundColor: '#f0f0f0', padding: '20px' }}>
  <!-- TODO: replace with actual user avatar image -->
  <img src="https://i.pravatar.cc/80" alt="Avatar" className="avatar" />
  <label htmlFor="name">Name:</label>
  <input type="text" id="name" disabled={true} />
  {/* This is a comment. */}
  <button onClick={handleClick}>Click</button>
</div>
▶ جرّب الكود

4. إنشاء مشروع React باستخدام Vite

(1) المتطلبات البيئية

الأداة متطلبات الإصدار أمر الفحص طريقة التثبيت
Node.js ≥ 18.0 node -v nodejs.org
npm ≥ 9.0 npm -v يتم تثبيته تلقائيًا مع Node.js
المحرر أي موصى به: VS Code

(2) إنشاء مشروع وتشغيله

BASH
# 1. Create a Project(react-ts = React + TypeScript Template)
npm create vite@latest my-react-app -- --template react-ts

# 2. Go to the project directory
cd my-react-app

# 3. Install Dependencies
npm install

# 4. Start the development server
npm run dev

الناتج:

TEXT 📖 للعرض فقط
  VITE v5.x  ready in 320ms

  ➜  Local:   http://localhost:5173/
  ➜  Network: http://192.168.1.100:5173/

افتح ملف http://localhost:5173/، وسترى صفحة الترحيب الافتراضية لـ Vite + React.

(3) هيكل دليل المشروع

BASH
my-react-app/
├── index.html              # Entrance HTML Documents(Vite Parsing Entry Point)
├── package.json            # Project Configuration and Dependencies
├── vite.config.ts          # Vite Profile
├── tsconfig.json           # TypeScript Layout
├── tsconfig.app.json       # Applications TS Layout
├── tsconfig.node.json      # Node.js Environment TS Layout
├── public/                 # Static Resources(Will not be compiled)
│   └── vite.svg
└── src/                    # Source Code Directory
    ├── main.tsx            # App Entry Point(Render the root component)
    ├── App.tsx             # Root Component
    ├── App.css             # Root Component Styles
    ├── index.css           # Global Styles
    └── assets/             # Resource Files(will be compiled)
        └── react.svg
الملف الغرض
index.html نقطة دخول الصفحة؛ يبدأ Vite التحليل من هنا
src/main.tsx إدخال JavaScript، عرض <App /> إلى #root
src/App.tsx المكون الجذري؛ تبدأ جميع المكونات الأخرى من هنا
vite.config.ts إعدادات Vite (الأسماء المستعارة، الخوادم الوكيلة، المكونات الإضافية، إلخ)

▶ مثال: إنشاء أبسط مكون في React

TSX
// ============================================
// Example:from  main.tsx The Complete Process for Navigating to the Page
// ============================================

// src/main.tsx —— App Entry Point
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import App from './App.tsx'
import './index.css'

createRoot(document.getElementById('root')!).render(
  <StrictMode>
    <App />
  </StrictMode>
)
▶ جرّب الكود
TSX
// src/App.tsx —— Root Component
function App() {
  return (
    <div>
      <h1>Hello, React!</h1>
      <p>This is my first one React Applications 🎉</p>
    </div>
  )
}

export default App
CSS
/* src/index.css —— Global Styles */
body {
  font-family: Arial, sans-serif;
  max-width: 600px;
  margin: 50px auto;
  text-align: center;
}


5. React DevTools

تُعد React DevTools أداة أساسية لتصحيح أخطاء تطبيقات React، حيث تتيح لك عرض شجرة المكونات، وخصائص المكونات (props)، والحالة (state)، والأداء.

طريقة التثبيت الإجراءات
ملحق Chrome ابحث عن "React Developer Tools" في متجر Chrome الإلكتروني
ملحقات فايرفوكس ابحث عن «React Developer Tools» في ملحقات فايرفوكس
تطبيق مستقل npx react-devtools

▶ مثال: عرض مكون باستخدام DevTools

بعد التثبيت، افتح «أدوات المطور» (F12)، وسترى علامتي تبويب جديدتين: المكونات وأداة تحليل الأداء:

JSX
// in  DevTools You can view these components in real time here Props and  State
function App() {
  const [count, setCount] = React.useState(0)
  return (
    <div>
      <Header title="Counter" />
      <Counter count={count} onIncrement={() => setCount(c => c + 1)} />
      <Footer year={2026} />
    </div>
  )
}

// Components The panel will display:
// ├── App
// │   ├── Header (props: { title: "Counter" })
// │   ├── Counter (props: { count: 0, onIncrement: fn })
// │   └── Footer (props: { year: 2026 })
▶ جرّب الكود

▶ المثال 4: الجمع بين العرض الشرطي في JSX والقوائم

JSX
function ProductCatalog({ products, isLoading, error }) {
  if (isLoading) return <p style={{ textAlign: 'center', padding: 40 }}>Loading products...</p>
  if (error) return <p style={{ color: '#ff4d4f', textAlign: 'center' }}>Error: {error}</p>
  if (products.length === 0) return <p style={{ textAlign: 'center', color: '#999' }}>No products found</p>

  return (
    <div style={{ maxWidth: 600, margin: '0 auto' }}>
      <h2>Product Catalog ({products.length})</h2>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(180px, 1fr))', gap: 16 }}>
        {products.map(product => (
          <div key={product.id} style={{ border: '1px solid #eee', borderRadius: 8, padding: 12 }}>
            <h4 style={{ margin: '0 0 8px' }}>{product.name}</h4>
            <p style={{ color: '#ff4d4f', fontWeight: 'bold', margin: '0 0 4px' }}>${product.price}</p>
            {product.inStock ? (
              <span style={{ color: '#52c41a', fontSize: 12 }}>In Stock</span>
            ) : (
              <span style={{ color: '#999', fontSize: 12 }}>Out of Stock</span>
            )}
          </div>
        ))}
      </div>
    </div>
  )
}

function CatalogPage() {
  const sampleProducts = [
    { id: 1, name: 'Keyboard', price: 79, inStock: true },
    { id: 2, name: 'Mouse', price: 49, inStock: true },
    { id: 3, name: 'Monitor', price: 399, inStock: false },
  ]
  return <ProductCatalog products={sampleProducts} isLoading={false} error={null} />
}
▶ جرّب الكود

▶ المثال 5: شامل — تحليل ملف الدخول لمشروع React

JSX
// package.json Key Dependencies
// {
//   "dependencies": { "react": "^18.3", "react-dom": "^18.3" },
//   "devDependencies": { "vite": "^5.0", "@types/react": "^18.3", "@types/react-dom": "^18.3" }
// }

// src/main.jsx - App Entry Point
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
import './index.css'

const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
)

// src/App.jsx - Root Component
import { useState } from 'react'

function App() {
  const [currentPage, setCurrentPage] = useState('home')

  return (
    <div style={{ fontFamily: 'sans-serif', maxWidth: 800, margin: '0 auto', padding: 20 }}>
      <nav style={{ display: 'flex', gap: 16, marginBottom: 24, borderBottom: '2px solid #1890ff', paddingBottom: 12 }}>
        {['home', 'about', 'contact'].map(page => (
          <button key={page} onClick={() => setCurrentPage(page)}
            style={{
              padding: '8px 16px', border: 'none', borderRadius: 4, cursor: 'pointer',
              background: currentPage === page ? '#1890ff' : '#f0f0f0',
              color: currentPage === page ? 'white' : '#333',
            }}>
            {page.charAt(0).toUpperCase() + page.slice(1)}
          </button>
        ))}
      </nav>
      <main>
        {currentPage === 'home' && (
          <div>
            <h1>Welcome to React</h1>
            <p>This is a minimal React app with Vite. Edit src/App.jsx and save to reload.</p>
            <p>Current time: {new Date().toLocaleTimeString()}</p>
          </div>
        )}
        {currentPage === 'about' && (
          <div>
            <h2>About</h2>
            <p>Built with React 18 + Vite for fast development and HMR.</p>
          </div>
        )}
        {currentPage === 'contact' && (
          <div>
            <h2>Contact</h2>
            <p>Email us at hello@example.com</p>
          </div>
        )}
      </main>
      <footer style={{ marginTop: 40, paddingTop: 12, borderTop: '1px solid #eee', color: '#999', fontSize: 13 }}>
        © 2026 React Tutorial. Built with Vite + React 18.
      </footer>
    </div>
  )
}

export default App


❓ أسئلة شائعة

س ما الفرق بين npm create vite@latest وnpx create-vite؟
ج كلاهما يؤديان نفس الوظيفة تمامًا. npm create vite@latest هي الصيغة الموصى بها لـ npm (تم تقديمها في الإصدار 7 وما بعده من npm)، والتي تبحث تلقائيًا عن أحدث حزمة create-vite وتقوم بتشغيلها. يمكن أيضًا استخدام npx create-vite. إذا كنت تستخدم pnpm أو yarn، فيمكنك استخدام pnpm create vite أو yarn create vite.
س لماذا لا يمكننا استخدام class في JSX — ولماذا يتعين علينا استخدام className؟
ج لأن class هي كلمة رئيسية محجوزة في JavaScript. وبما أن JSX هي في الأساس لغة JavaScript، فلا يمكننا استخدام class. أثناء العرض، يقوم React تلقائيًا بتحويل className إلى سمة HTML class. وبالمثل، forhtmlFor.
س لماذا تستخدم السمة style في JSX أقواسًا معقوفة مزدوجة {{}}؟
ج تشير الأقواس المعقوفة الخارجية إلى «تعبير JavaScript مضمن في JSX»، بينما تشير الأقواس المعقوفة الداخلية إلى «هذا كائن JavaScript». لذلك، فإن style={{ color: 'red' }} تعني: تمرير كائن JS { color: 'red' } كقيمة للسمة style.
س ما الفرق بين ملفات .tsx و.ts في المشروع؟
ج يمكن أن تحتوي ملفات .tsx على صيغة JSX (أي يمكنك كتابة علامات HTML بلغة TypeScript)، بينما لا يمكن لملفات .ts ذلك. يجب أن تحمل جميع الملفات التي تحتوي على مكونات React اللاحقة .tsx. أما الملفات التي تحتوي على منطق بحت (مثل الدوال المساعدة وتعريفات الأنواع) فيمكنها استخدام اللاحقة .ts.
س ما الفرق بين Vite وWebpack؟ ولماذا اختار البرنامج التعليمي استخدام Vite؟
ج يستخدم Vite وحدات ES الأصلية في خادم التطوير الخاص به، مما يتيح بدء التشغيل البارد في غضون أجزاء من الألف من الثانية؛ أما Webpack فيحتاج إلى تجميع التطبيق بأكمله قبل بدء التشغيل، لذا كلما كبر حجم المشروع، زادت بطئه. كما أن ميزة HMR (استبدال الوحدات أثناء التشغيل) في Vite أسرع أيضًا لأنها لا تحتاج سوى إلى استبدال الوحدات التي تم تعديلها. بالنسبة لعمليات البناء في بيئة الإنتاج، يستخدم كلاهما Rollup/esbuild للتجميع، لذا لا يوجد فرق كبير في الأداء. تم اختيار Vite لهذا البرنامج التعليمي لأنه يوفر تجربة تطوير أفضل ويمثل اتجاهًا جديدًا في مجتمع React.

📖 ملخص


📝 تمارين

  1. تمرين أساسي (مستوى الصعوبة ⭐): أنشئ مشروعًا جديدًا باستخدام React و TypeScript عبر Vite، وقم بتعديل App.tsx لعرض اسمك وتقديمًا موجزًا عن نفسك.
  2. تمرين (مستوى الصعوبة: ⭐⭐): أنشئ متغيرًا باسم const isLoggedIn = true في مكون App، واستخدم العامل الثلاثي في JSX لعرض عبارة «مرحبًا بعودتك» أو «يرجى تسجيل الدخول».
  3. التحقيق (مستوى الصعوبة: ⭐): افتح لوحة «المكونات» (Components) في React DevTools، واطلع على هيكل شجرة المكونات الخاص بالقالب الافتراضي لـ Vite، ثم التقط لقطة شاشة واحفظها.
Web-Tutorial.com

فريق Web-Tutorial التقني

منصة دروس برمجية يديرها عدة مطورين. كل درس يتم كتابته ومراجعته بواسطة مطورين متخصصين في المجال. نعمل على ضمان دقة وموثوقية المحتوى — إذا لاحظت أي مشكلة، فيرجى إخبارنا.

100%