NelsonLabs
React Fundamentals/JSX — HTML inside JavaScript

JSX — HTML inside JavaScript

JSX is the HTML-like syntax you write inside React components. It's not real HTML — it's JavaScript with a special syntax that gets compiled to regular function calls. Once you understand what JSX actually is, it stops feeling magical.

JSX compiles to JavaScript
jsx
// What you write (JSX)
const element = <h1 className="title">Hello</h1>;

// What React compiles it to
const element = React.createElement(
  "h1",
  { className: "title" },
  "Hello"
);

// You write JSX because it's readable. React does the rest.

JSX rules

JSX syntax rules
jsx
// 1. className instead of class
<div className="card">...</div>

// 2. htmlFor instead of for (on labels)
<label htmlFor="email">Email</label>

// 3. All tags must be closed
<img src="photo.jpg" alt="..." />     // self-closing
<br />
<input type="text" />

// 4. Must return a single root element — use fragments to group
function Component() {
  return (
    <>                    {/* Fragment — renders nothing extra in the DOM */}
      <h1>Title</h1>
      <p>Paragraph</p>
    </>
  );
}

// 5. JavaScript expressions go inside curly braces {}
const name = "Nelson";
const count = 42;
return <p>Hello, {name}! You have {count} messages.</p>;

// 6. Objects need double curly braces (outer = JSX expression, inner = object)
<div style={{ color: "#EDE8DC", padding: "1rem" }}>...</div>
Conditional rendering
jsx
// Ternary — show different content based on a condition
function Greeting({ isLoggedIn }) {
  return (
    <div>
      {isLoggedIn ? <p>Welcome back!</p> : <p>Please log in.</p>}
    </div>
  );
}

// Short-circuit — render nothing or something
function Notification({ count }) {
  return (
    <div>
      {count > 0 && <span className="badge">{count}</span>}
    </div>
  );
}
// If count is 0 (falsy), nothing renders
// If count is 5, the span renders

// null returns nothing — useful for conditional components
function Sidebar({ isOpen }) {
  if (!isOpen) return null;
  return <aside>Sidebar content</aside>;
}