JSX in Practice: From Syntax to UI
JSX (JavaScript XML) is the syntax that makes React declarative and easy to read. It looks like HTML, but it's actually a powerful JavaScript abstraction. Understanding how to use it effectively is the most crucial skill for any React developer. Let's dive deep into how JSX works in real-world scenarios.
1. JSX vs. `React.createElement`
Behind the scenes, JSX is just "syntactic sugar" for a standard JavaScript function call: `React.createElement()`. A tool called Babel compiles your JSX into this function.
✔️ You Write This (JSX)
const element = (
<h1 className="greeting">
Hello, world
</h1>
);🤖 Babel Compiles This
const element = React.createElement(
'h1',
{className: 'greeting'},
'Hello, world'
);Knowing this relationship is key. It clarifies that JSX is not HTML; it's a way to create JavaScript objects that React uses to build the DOM.
2. Embedding Expressions: The Power of ``
The curly braces `` are your escape hatch back into JavaScript. You can put any valid JavaScript expression inside them.
- Variables:
<h1>Hello, {user.name}</h1> - Math:
<p>Total: {2 + 2}</p> - Function Calls:
<div>{formatDate(user.joined)}</div> - Ternary Operators:
{isLoading ? <Spinner /> : <Content />} - Logical `&&` Operator:
{showWarning && <Warning />}
Important: You cannot put statements (like `if`, `for`, `while`) inside ``. You must use expressions that resolve to a value.
3. Specifying Attributes
JSX attributes are similar to HTML but follow JavaScript's `camelCase` naming convention.
- `className` (not `class`):
<div className="card">...</div> - `htmlFor` (not `for`):
<label htmlFor="email">Email</label> - Event Handlers:
<button onClick={handleClick}>Click Me</button> - Style (Double Braces): The `style` attribute takes a JavaScript object. This results in double braces: one for the JSX expression, and one for the object literal.
<div style={{ color: 'red', fontSize: '16px' }}>...</div> - Boolean Attributes: You can pass `true` explicitly (
disabled={true}) or just by including the prop (disabled). To pass `false`, you must use braces (disabled={false}).
4. The Single Root Element Rule & Fragments
A React component must return a single root element. React's diffing algorithm needs one "root" to check against.
❌ Bad Practice (Error)
return (
<h1>Title</h1>
<p>Text</p>
);This will cause a syntax error.
✔️ Good Practice
return (
<>
<h1>Title</h1>
<p>Text</p>
</>
);Wrapped in a Fragment (`...`).
You can either wrap your elements in a `div` (which adds an extra node to the DOM) or use a Fragment (<React.Fragment>...</React.Fragment> or the shorthand <>...</>) which doesn't render any extra HTML.
5. Rendering Lists with `.map()` and `key`
You'll often need to render a list of items. The standard way is to use the `.map()` array method inside an expression block. When you do this, React requires a unique `key` prop for each item to help it identify which items have changed, been added, or removed.
const todos = [
{ id: 'a', text: 'Learn JSX' },
{ id: 'b', text: 'Build App' },
];
return (
<ul>
{todos.map(todo => (
<li key={todo.id}>
{todo.text}
</li>
))}
</ul>
);6. JSX and Security (XSS)
By default, React DOM **escapes** any values embedded in JSX before rendering them. This means you are protected from Cross-Site-Scripting (XSS) attacks.
If `user.name` is <script>alert('hack')</script>, React will not execute the script. It will render the literal text on the screen, foiling the attack.
Key Takeaway: JSX is the heart of React. Master its rules: use `{}` for expressions, `className` for styling, and `<>` for grouping, and you'll be able to build any UI you can imagine.