תחביר JSX
מהו JSX?
JSX (JavaScript XML) הוא תחביר שמאפשר לכתוב קוד שנראה כמו HTML ישירות בתוך JavaScript. חשוב להבין שזה אינו HTML אמיתי - לפני שהקוד מגיע לדפדפן הוא מתקמפל ל-JavaScript רגיל. JSX הוא בסך הכול "סוכר תחבירי" שהופך את בניית הממשק לקריאה ונוחה יותר.
// JSX
const element = <h1>שלום עולם!</h1>;
// מה שזה הופך להיות (React.createElement)
const element = React.createElement('h1', null, 'שלום עולם!');
כללי תחביר בסיסיים
1. אלמנט שורש יחיד
כל קומפוננטה חייבת להחזיר אלמנט עוטף אחד בלבד. אפשר לעטוף את התוכן ב-div, ואם לא רוצים להוסיף תגית מיותרת ל-DOM - להשתמש ב-Fragment:
// ❌ שגוי - שני אלמנטים שורש
function Bad() {
return (
<h1>כותרת</h1>
<p>תוכן</p>
);
}
// ✅ נכון - עטיפה ב-div
function Good() {
return (
<div>
<h1>כותרת</h1>
<p>תוכן</p>
</div>
);
}
// ✅ נכון - שימוש ב-Fragment
function Better() {
return (
<>
<h1>כותרת</h1>
<p>תוכן</p>
</>
);
}
2. סגירת תגיות
כל התגיות חייבות להיסגר:
// ✅ תגיות עם תוכן
<div>תוכן</div>
<p>פסקה</p>
// ✅ תגיות self-closing
<img src="image.jpg" />
<br />
<input type="text" />
<hr />
3. camelCase לתכונות
מכיוון ש-JSX הוא בעצם JavaScript, חלק משמות התכונות משתנים לעומת HTML רגיל ונכתבים ב-camelCase. שימו לב במיוחד למילים השמורות class ו-for, שהופכות ל-className ו-htmlFor:
// HTML רגיל // JSX
// class="..." → className="..."
// for="..." → htmlFor="..."
// onclick="..." → onClick={...}
// tabindex="..." → tabIndex={...}
<label htmlFor="name" className="label">
שם:
<input id="name" tabIndex={1} />
</label>
ביטויים בסוגריים מסולסלים
הסוגריים המסולסלים {} הם הגשר בין ה-JSX ל-JavaScript: כל ביטוי שנכתב בתוכם מחושב, והתוצאה מוצגת במסך. אפשר להכניס אליהם משתנים, חישובים, קריאות לפונקציות ותנאים:
משתנים
const name = "דני";
const age = 25;
return (
<div>
<h1>שלום {name}!</h1>
<p>גיל: {age}</p>
</div>
);
ביטויים חשבוניים
return (
<div>
<p>2 + 2 = {2 + 2}</p>
<p>מספר אקראי: {Math.random()}</p>
<p>גיל בעוד 10 שנים: {age + 10}</p>
</div>
);
קריאות לפונקציות
function formatDate(date) {
return date.toLocaleDateString('he-IL');
}
return <p>תאריך: {formatDate(new Date())}</p>;
ביטויי תנאי (Ternary)
const isLoggedIn = true;
return (
<div>
{isLoggedIn ? <p>שלום משתמש!</p> : <p>אנא התחבר</p>}
</div>
);
אובייקטים ומערכים
const user = { name: "דני", age: 25 };
const colors = ["אדום", "ירוק", "כחול"];
return (
<div>
<p>שם: {user.name}</p>
<p>צבע ראשון: {colors[0]}</p>
</div>
);
סגנונות (Styles)
Inline Styles
// סגנונות כאובייקט JavaScript
const style = {
color: 'blue',
fontSize: '20px', // camelCase!
backgroundColor: '#f0f0f0',
padding: '10px'
};
return <p style={style}>טקסט מעוצב</p>;
// או inline
return (
<p style={{ color: 'red', fontWeight: 'bold' }}>
טקסט אדום ומודגש
</p>
);
CSS Classes
// App.css
// .title { color: blue; font-size: 24px; }
// .highlight { background-color: yellow; }
import './App.css';
function App() {
return (
<h1 className="title highlight">כותרת</h1>
);
}
Classes דינמיים
const isActive = true;
const isError = false;
return (
<div className={`box ${isActive ? 'active' : ''} ${isError ? 'error' : ''}`}>
תוכן
</div>
);
Fragments
Fragment מאפשר לקבץ כמה אלמנטים יחד מבלי להוסיף תגית עוטפת מיותרת ל-DOM. הוא פותר בדיוק את מגבלת "אלמנט השורש היחיד", בלי לזהם את מבנה העמוד ב-div נוסף:
import { Fragment } from 'react';
// תחביר מלא
function List() {
return (
<Fragment>
<li>פריט 1</li>
<li>פריט 2</li>
<li>פריט 3</li>
</Fragment>
);
}
// תחביר מקוצר (נפוץ יותר)
function List() {
return (
<>
<li>פריט 1</li>
<li>פריט 2</li>
<li>פריט 3</li>
</>
);
}
// עם key (רק בתחביר המלא)
function Items({ items }) {
return items.map(item => (
<Fragment key={item.id}>
<dt>{item.term}</dt>
<dd>{item.description}</dd>
</Fragment>
));
}
הערות ב-JSX
function App() {
return (
<div>
{/* זו הערה ב-JSX */}
<h1>כותרת</h1>
{/*
הערה
בכמה
שורות
*/}
<p>תוכן</p>
</div>
);
}
דברים שאי אפשר לעשות ב-JSX
בתוך הסוגריים המסולסלים אפשר לכתוב ביטויים (expressions) בלבד - כלומר קוד שמחזיר ערך. משפטי בקרה כמו if או לולאת for אינם ביטויים, ולכן במקומם משתמשים ב-ternary, באופרטור && ובמתודה map:
// ❌ שגוי - if/else רגיל לא עובד בתוך JSX
function Bad() {
return (
<div>
{if (condition) { <p>כן</p> }} // שגיאה!
</div>
);
}
// ✅ השתמשו ב-ternary או &&
function Good() {
return (
<div>
{condition ? <p>כן</p> : <p>לא</p>}
{condition && <p>מוצג רק אם true</p>}
</div>
);
}
// ❌ for loop ישירות - לא עובד
function Bad() {
return (
<ul>
{for (let i = 0; i < 3; i++) { <li>{i}</li> }} // שגיאה!
</ul>
);
}
// ✅ השתמשו ב-map
function Good() {
return (
<ul>
{[0, 1, 2].map(i => <li key={i}>{i}</li>)}
</ul>
);
}
סיכום תחביר JSX
| כלל | דוגמה |
|---|---|
| אלמנט שורש יחיד | <> ... </> |
| סגירת תגיות | <img /> |
| className | <div className="box"> |
| htmlFor | <label htmlFor="id"> |
| ביטויים בסוגריים | {variable} |
| Inline styles | style={{ color: 'red' }} |
| הערות | {/* הערה */} |
הקודם: ← התקנה והגדרות
הבא: קומפוננטות →
בדקו את עצמכם
נסו לענות לבד לפני שאתם פותחים את התשובה.
-
איך כותבים class של CSS ב-JSX?
הצגת התשובה
תשובה ד. class היא מילה שמורה ב-JavaScript, ולכן JSX משתמש ב-className.
-
מה מחזירה קומפוננטה שמנסה להחזיר שני אלמנטים צמודים בלי עטיפה?
הצגת התשובה
תשובה ב. עוטפים ב-<>...</> (Fragment), שלא מוסיף אלמנט ל-DOM.
-
איך מכניסים ערך JavaScript לתוך JSX?
הצגת התשובה
תשובה ג. סוגריים מסולסלים בודדים מפעילים ביטוי JavaScript.