Menu

מה זה JSX? כללי התחביר של JSX ב-React עם דוגמאות

JSX הוא הרחבת תחביר ל-JavaScript שמאפשרת לכתוב markup שדומה ל-HTML בתוך קומפוננטות React. למדו את הכללים שלו: אלמנט שורש אחד, תגיות סגורות, className, מאפיינים ב-camelCase, סוגריים מסולסלים, סגנונות inline, הערות, ולאיזה קוד הוא מתקמפל.

בדף הזה יש עורכים שאפשר להריץ - לערוך, להריץ ולראות את הפלט מיד.

JSX הוא הרחבת תחביר ל-JavaScript שמאפשרת לכתוב markup שדומה ל-HTML בתוך הקוד. קומפוננטות React מחזירות JSX כדי לתאר מה צריך להופיע על המסך, וכלי build מקמפל אותו לקריאות פונקציה רגילות של JavaScript. הוא נראה כמו HTML, אבל כמה כללים שונים, וסוגריים מסולסלים מאפשרים להכניס כל ערך JavaScript לתוך ה-markup.

כל מה שבתוך {} הוא JavaScript: מאפיין, קריאה למתודה, ואפילו map שהופך מערך לפריטי רשימה. הוסיפו 'design' למערך skills וגם הספירה וגם הרשימה יתעדכנו.

כללי JSX

החזירו אלמנט שורש אחד

קומפוננטה מחזירה ערך אחד, ולכן ה-JSX שלה צריך הורה אחד. שני אחים ברמה העליונה הם שגיאת תחביר. כשלא רוצים <div> נוסף בדף, עטפו אותם ב-fragment, <>...</>:

// Error: Adjacent JSX elements must be wrapped in an enclosing tag
return (
    <h1>Title</h1>
    <p>Text</p>
);

// OK: a fragment groups them without adding a DOM element
return (
    <>
        <h1>Title</h1>
        <p>Text</p>
    </>
);

כשצריך key על הקבוצה, השתמשו בצורה הארוכה <Fragment key={id}>; ראו fragments.

סגרו כל תגית

HTML מאפשר להשאיר חלק מהתגיות פתוחות. JSX לא. אלמנטים בלי ילדים נסגרים בעצמם עם />: <img />, <br />, <input />, והקומפוננטות שלכם כמו <Avatar />.

השתמשו ב-className, htmlFor ובמאפיינים ב-camelCase

מאפייני JSX הופכים למפתחות של אובייקט JavaScript, ולכן הם עוקבים אחרי מוסכמות השמות של JavaScript. class ו-for הן מילים שמורות ב-JavaScript, ולכן JSX משתמש ב-className וב-htmlFor. מאפיינים של כמה מילים וכל ה-event handlers כתובים ב-camelCase: tabIndex, maxLength, autoFocus, onClick, onChange. שני חריגים שומרים על המקפים שלהם: מאפייני aria-* ו-data-* נכתבים בדיוק כמו ב-HTML.

שנו את className="field" ל-class="field". התווית שומרת על העיצוב שלה, כי React מגדירה את המאפיין בכל זאת, אבל build של פיתוח רושם "Invalid DOM property class. Did you mean className?". התצוגה המקדימה רצה כמו build של פרודקשן, אז לא תראו את האזהרה הזו כאן; השתמשו ב-className. מאפיין מסוג מחרוזת משתמש במירכאות (type="email"); כל ערך אחר משתמש בסוגריים מסולסלים (maxLength={40}, disabled={false}).

סוגריים מסולסלים מקבלים ביטויים, לא משפטים

בתוך {} אפשר לכתוב כל דבר שמייצר ערך: משתנה, חשבון, קריאה לפונקציה, אופרטור טרנרי, &&, תבנית מחרוזת (template literal). משפטים כמו if, for ו-const לא מייצרים ערך, ולכן הם לא יכולים להופיע שם. עשו את העבודה לפני ה-return, או השתמשו בצורה של ביטוי:

הסתכלו היטב לפני שאתם לוחצים: בדף מופיע 0 מיותר. count && <p>...</p> מחושב ל-0 כשהספירה היא אפס, ו-React מרנדרת מספרים, גם אפס. שנו אותו ל-count > 0 && <p>You have mail.</p> וה-0 ייעלם. false, null, undefined ו-true לא מרנדרים כלום, ולכן ערך בוליאני לפני && בטוח. הדף על רינדור מותנה מכסה את הדפוסים.

סגנונות inline משתמשים באובייקט

המאפיין style מקבל אובייקט JavaScript, לא מחרוזת CSS. מכאן המראה של "סוגריים כפולים": הזוג החיצוני אומר "כאן JavaScript", והזוג הפנימי הוא האובייקט עצמו. שמות המאפיינים ב-camelCase (backgroundColor, fontSize), ומספר רגיל פירושו פיקסלים ברוב מאפייני הגודל.

מכיוון שהסגנון הוא אובייקט, אפשר לחשב אותו מ-state כמו כל ערך אחר. נסו לשנות את fontSize: big ? 24 : 16 ל-fontSize: big ? '2em' : '1em': מחרוזות מועברות כמו שהן, עם היחידה שלהן.

הערות

הערה בתוך JSX נכתבת בסוגריים מסולסלים: {/* this is a comment */}. הערות HTML (<!-- -->) הן שגיאת תחביר. מחוץ ל-markup, בגוף הפונקציה, הערות // רגילות עובדות כרגיל.

return (
    <div>
        {/* The header is hidden on small screens */}
        <Header />
    </div>
);

המרת HTML ל-JSX

הדבקת HTML לתוך קומפוננטה היא צעד ראשון נפוץ, ורובו עובד. אלה השינויים שבדרך כלל צריך לעשות:

  • class הופך ל-className, ו-for הופך ל-htmlFor.
  • תגיות ריקות נסגרות בעצמן: <br> הופך ל-<br />, ו-<img src="a.png"> הופך ל-<img src="a.png" />.
  • style="color: red; font-size: 14px" הופך ל-style={{ color: 'red', fontSize: 14 }}.
  • מאפייני אירועים מקבלים פונקציה, לא מחרוזת: onclick="save()" הופך ל-onClick={save}.
  • שמות מאפיינים הופכים ל-camelCase: tabindex הופך ל-tabIndex, וה-stroke-width של SVG הופך ל-strokeWidth.
  • <!-- comments --> הופכות ל-{/* comments */}.
  • כמה אלמנטים ברמה העליונה צריכים הורה אחד או fragment.

ממירי HTML ל-JSX אונליין עושים את הצעדים האלה בשבילכם, אבל כשמכירים אותם קל לקרוא את הודעות השגיאה כשמפספסים אחד.

לאיזה קוד JSX מתקמפל

דפדפנים לא יכולים להריץ JSX. קומפיילר (כמו Babel, SWC או Oxc, ש-Vite וה-frameworks מריצים בשבילכם) הופך כל תגית לקריאת פונקציה מתוך react/jsx-runtime:

// What you write
const element = <h1 className="title">Hello, {name}</h1>;
const button = <Button size="small">OK</Button>;
// What the compiler produces (roughly)
import { jsx as _jsx, jsxs as _jsxs } from 'react/jsx-runtime';

const element = _jsxs('h1', { className: 'title', children: ['Hello, ', name] });
const button = _jsx(Button, { size: 'small', children: 'OK' });

תגית באותיות קטנות הופכת למחרוזת ('h1', אלמנט HTML), תגית שמתחילה באות גדולה הופכת להפניה לפונקציה שלכם (Button), המאפיינים הופכים לאובייקט ה-props, והתוכן הופך ל-children. הגדרות ישנות יותר קימפלו במקום זאת ל-React.createElement(type, props, ...children), ולכן קבצים ישנים מתחילים ב-import React from 'react' גם כשהם אף פעם לא מזכירים את React. הקריאה מחזירה אובייקט פשוט שנקרא React element. אפשר להדפיס אחד:

הקונסול מראה ש-heading הוא סתם נתונים: טיפוס 'h3' ואובייקט props. זו גם הסיבה שאפשר לשמור JSX במשתנים, להעביר אותו לפונקציות ולהחזיר אותו מהן.

JSX מבצע escape לטקסט בשבילכם

כל מחרוזת שמכניסים בסוגריים מסולסלים מרונדרת כטקסט, אף פעם לא כ-HTML. אם משתמש מקליד <img src=x onerror=alert(1)> בתיבת תגובה, React מציגה את התווים האלה על המסך במקום ליצור תגית תמונה. זה חוסם כברירת מחדל את הצורה הנפוצה ביותר של cross-site scripting (XSS).

הפסקה הראשונה מדפיסה את התגיות כתווים רגילים. השנייה משתמשת ב-dangerouslySetInnerHTML, שמדלג על ה-escape ומכניס את המחרוזת כ-HTML אמיתי, ולכן "our own" מודגש. השם הארוך הוא אזהרה: העבירו לשם רק HTML שאתם עצמכם יצרתם או ניקיתם עם sanitizer כמו DOMPurify. העברת קלט משתמש לשם פותחת מחדש את פרצת ה-XSS ש-JSX סגר.

שאלות נפוצות

מה פירוש ראשי התיבות JSX?

JSX הם ראשי תיבות של JavaScript XML. זו הרחבת תחביר שמאפשרת לכתוב markup שנראה כמו HTML בתוך קוד JavaScript.

האם JSX זה HTML?

לא. JSX נראה כמו HTML אבל מתקמפל לקריאות פונקציה של JavaScript שיוצרות אלמנטים של React. לכן הוא משתמש ב-className במקום class, בשמות מאפיינים ב-camelCase, ודורש שכל תגית תיסגר.

אפשר להשתמש ב-React בלי JSX?

כן. JSX הוא אופציונלי: אפשר לקרוא ישירות ל-createElement('h1', { className: 'title' }, 'Hello') מתוך react. כמעט כל קוד React משתמש ב-JSX כי הרבה יותר קל לקרוא markup מקונן.

למה אי אפשר לכתוב משפט if בתוך JSX?

סוגריים מסולסלים ב-JSX מקבלים ביטויים, כלומר דברים שמייצרים ערך, ו-if הוא משפט (statement). השתמשו באופרטור טרנרי (cond ? a : b), ב-&&, או חשבו את הערך במשתנה לפני ה-return.

איך כותבים הערה ב-JSX?

עטפו הערת JavaScript בסוגריים מסולסלים: {/* like this */}. הערות HTML (<!-- -->) הן שגיאת תחביר ב-JSX.

איור של שפות התכנות ב-Coddy

ללמוד תכנות עם Coddy

להתחיל