React course menu
JSX in React: Syntax, Expressions and Rules
Learn JSX, the HTML-like syntax of React: embedding JavaScript expressions with curly braces, attributes like className and style, returning a single root with fragments, self-closing tags, comments, and how JSX compiles to JavaScript.
On this page
JSX lets you write HTML-like markup inside JavaScript. It is how React components describe what to show.
const heading = <h1 className="title">Welcome</h1>;JSX is not HTML and not a string. A build tool (Vite, Next.js) compiles it into ordinary JavaScript function calls that create React elements. The line above becomes roughly:
const heading = React.createElement("h1", { className: "title" }, "Welcome");You could write createElement calls yourself, but JSX is far easier to read, so everyone uses it.
JavaScript inside JSX with curly braces#
Put any JavaScript expression (something that produces a value) inside { }:
export default function App() {
const name = "Priya";
const price = 499;
const quantity = 3;
const today = new Date(2026, 9, 24);
return (
<div>
<h2>Hello, {name.toUpperCase()}!</h2>
<p>Total: ₹{price * quantity}</p>
<p>Order date: {today.toDateString()}</p>
<p>Items in stock: {[1, 2, 3].length}</p>
</div>
);
}Expressions work: variables, maths, function calls, method calls, the ternary operator. Statements do not: you cannot put if, for or const inside { }. Use them before the return, or use expressions instead (see Conditional Rendering).
Attributes#
JSX attributes look like HTML, with a few differences because JSX is JavaScript:
classis a reserved word in JavaScript, so useclassName;foron labels becomeshtmlFor.- Attributes are camelCase:
onClick,tabIndex,maxLength(exceptaria-*anddata-*, which keep their dashes). - String values use quotes; any other value uses braces:
<img src={photoUrl} width={120} />. styletakes a JavaScript object with camelCase property names, so it has double braces: the outer pair for JavaScript, the inner pair for the object.
export default function App() {
const avatarSize = 64;
const highlight = { backgroundColor: "#fff3bf", padding: "8px 12px", borderRadius: 6 };
return (
<div>
<label htmlFor="email">Email</label>{" "}
<input id="email" type="email" placeholder="you@example.com" maxLength={40} />
<p className="note" style={highlight}>
Avatar size: {avatarSize}px
</p>
<p style={{ color: "teal", fontWeight: "bold" }}>Inline style with double braces</p>
</div>
);
}A number such as borderRadius: 6 is treated as pixels. {" "} adds a space between the label and the input, because JSX removes line breaks between elements.
One root element, or a fragment#
A component returns one element. To return several side by side, wrap them in a parent, or in a fragment <>...</>, which groups them without adding an extra element to the page:
export default function App() {
return (
<>
<h3>Fragments</h3>
<p>These two elements have no extra wrapper around them.</p>
</>
);
}Every tag must be closed#
In JSX, tags that have no content must close themselves: <img />, <input />, <br />, <hr />. Forgetting the slash is a syntax error, unlike in HTML.
Comments#
Inside JSX, comments go in braces: {/* like this */}. Outside JSX, normal JavaScript comments work.
JSX is a value#
Because JSX produces values, you can store it in variables, pass it to functions and return it from functions:
function badge(text) {
return <span style={{ border: "1px solid #888", borderRadius: 4, padding: "0 6px" }}>{text}</span>;
}
export default function App() {
const greeting = <strong>Good morning</strong>;
return (
<p>
{greeting}, your plan is {badge("Pro")} {/* a function returning JSX */}
</p>
);
}Safe by default#
Text inside { } is always inserted as text, never as HTML. If a user's name is <b>hacker</b>, React shows those characters literally rather than making text bold, which protects against cross-site scripting (XSS). React has an escape hatch, dangerouslySetInnerHTML, whose name is a warning: only use it with HTML you trust or have sanitised.
Common mistakes#
Practice#
Practice exercise
Write a component that shows a product card: the name "Wireless Mouse" in an <h3>, the price 899 formatted as ₹899.00 using toFixed(2), and a green "In stock" message using an inline style.
Show hint
Store the price in a variable and write ₹{price.toFixed(2)}. For the style, pass style={{ color: "green" }}.
Show solution
export default function App() {
const name = "Wireless Mouse";
const price = 899;
return (
<div className="card">
<h3>{name}</h3>
<p>₹{price.toFixed(2)}</p>
<p style={{ color: "green" }}>In stock</p>
</div>
);
}Key takeaway#
Next: Components.
Finished this lesson?