Skip to main content

2.1 JSX & Rendering Elements

← Back to Chapter 2: React Fundamentals

JSX (JavaScript XML) is a syntax extension for JavaScript that allows you to write HTML-like markup directly inside your JavaScript code. It pairs the rendering logic of UI elements with their behavior logic, creating cohesive, declarative components.


1. What is JSX?​

Browsers do not understand JSX natively. During the build process, a compiler (such as Babel, SWC, or Vite/esbuild) converts JSX into standard JavaScript function calls.

Behind the Scenes: The JSX Transform​

// What you write (JSX):
const element = <h1 className="hero-title">Hello, React!</h1>;
// What the compiler outputs (Classic React.createElement):
const element = React.createElement(
"h1",
{ className: "hero-title" },
"Hello, React!"
);

// What React 17+ outputs (New JSX Transform):
import { jsx as _jsx } from "react/jsx-runtime";
const element = _jsx("h1", {
className: "hero-title",
children: "Hello, React!"
});

The resulting element is a plain JavaScript object describing the DOM node:

{
type: 'h1',
props: {
className: 'hero-title',
children: 'Hello, React!'
}
}

2. Rules of Writing JSX​

Rule 1: Return a Single Root Element​

Every component must return a single root element. If you need to return multiple adjacent elements without adding an extra <div> to the real DOM, wrap them in a Fragment (<React.Fragment> or <>):

function NavigationBar() {
return (
<>
<a href="/home">Home</a>
<a href="/docs">Docs</a>
<a href="/contact">Contact</a>
</>
);
}
Why Single Root?

Under the hood, a component is a function returning a JavaScript value. A function cannot return multiple separate objects simultaneously without wrapping them in an array or parent container object.

Rule 2: Close All Tags​

Every tag in JSX must be explicitly closed. Self-closing tags require a trailing slash:

// ✅ Correct:
<img src="/logo.png" alt="Logo" />
<input type="text" placeholder="Search..." />
<br />

Rule 3: camelCase Most Attributes​

Because JSX turns into JavaScript objects and class and for are reserved keywords in JS:

  • Use className instead of class
  • Use htmlFor instead of for
  • Use tabIndex instead of tabindex
  • Inline styles take an object with camelCase properties: style={{ backgroundColor: "#1e293b", padding: "12px" }}

3. Embedding JavaScript Expressions with {}​

Any valid JavaScript expression (something that evaluates to a value) can be embedded inside JSX using curly braces {}:

const user = {
firstName: "Sarwvidya",
lastName: "Sharma",
avatar: "https://avatar.dev/sarvy.png"
};

function formatName(u) {
return `${u.firstName} ${u.lastName}`;
}

function ProfileCard() {
return (
<div className="card">
<img src={user.avatar} alt={formatName(user)} />
<h3>{formatName(user)}</h3>
<p>Calculated score: {10 + 25 * 2}</p>
</div>
);
}
Expressions vs Statements

Inside {} you can only place expressions (ternary operations, function calls, variable lookups, .map()). You cannot put statements like if...else, for loops, or switch statements directly inside {}.


4. Rendering Elements into the DOM​

In React 18 and 19, the modern entry point uses createRoot from react-dom/client:

// main.jsx / index.jsx
import React from 'react';
import { createRoot } from 'react-dom/client';
import App from './App';

const container = document.getElementById('root');
const root = createRoot(container);

root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);

React.StrictMode​

<React.StrictMode> is a developer-only tool that does not render any visible UI. It:

  1. Double-invokes functions and lifecycle effects in development to expose unintended side-effects.
  2. Warns about deprecated APIs and legacy patterns.
  3. Checks for safe usage of concurrent features.

5. Summary Checklist​

  • JSX is a declarative syntax sugar for React.createElement() that produces lightweight Virtual DOM element trees.
  • All tags must be closed and grouped into a single root (use Fragments <> ... </> to avoid redundant wrapper divs).
  • Use camelCase for DOM attributes (className, htmlFor, onClick).
  • Embed any JavaScript expression inside {} anywhere within text or attributes.
  • React uses createRoot(container).render(<App />) to bind the Virtual DOM tree to the browser runtime.