JSX
Write UI with JSX syntax — expressions, attributes, fragments, and the rules that keep markup valid JavaScript.
JSX Is Syntax Sugar
JSX looks like HTML embedded in JavaScript but compiles to `React.createElement` calls (or JSX runtime imports in modern setups). The compiler handles transforming tags, attributes, and children into JavaScript objects describing UI.
Because JSX is JavaScript, you can embed expressions with `{}`, spread props, and use any valid expression as a child. You cannot use statements inside `{}` without wrapping in an IIFE — prefer computing values above the return.
- Compiles to createElement or jsx runtime
- Expressions in `{}`
- Not a separate template language
const element = <h1 className="title">{user.name}</h1>;Attributes and DOM Differences
JSX uses camelCase for attributes: `className` instead of `class`, `htmlFor` instead of `for`. Event handlers use camelCase: `onClick`, `onChange`. Pass functions, not strings.
Boolean attributes like `disabled` and `checked` work as expected. Custom data attributes use lowercase: `data-testid`. Style accepts an object with camelCase CSS properties, not a string — prefer CSS classes for maintainability.
- className, htmlFor, camelCase events
- Style as object, prefer classes
- data-* attributes lowercase
<button className="btn" onClick={handleClick} disabled={isLoading}>
Submit
</button>Fragments and Multiple Roots
Components must return a single parent element — use Fragments (`<>...</>` or `<Fragment>`) to group siblings without adding DOM nodes. Fragments are essential for table rows, list groups, and layout-free composition.
React 19+ allows documents with multiple roots in some cases, but fragments remain the standard pattern for component return values that need sibling elements.
- Single parent required per return
- Fragments avoid extra DOM nodes
- Short syntax `<>...</>`
return (
<>
<Header />
<Main />
</>
);Conditional and List Rendering
Render conditionally with `&&`, ternary operators, or early returns. Choose readability — nested ternaries in JSX become hard to review. Extract complex conditions to variables or subcomponents.
Render lists with `map`, always providing a stable `key` prop from data IDs — never array index when order can change. Keys help React match items correctly during insert, delete, and reorder operations.
- && and ternary for conditionals
- map for lists with stable keys
- Avoid index keys on reorderable lists
{items.map(item => (
<li key={item.id}>{item.label}</li>
))}Security and JSX
React escapes text interpolated in JSX by default, preventing XSS from string values. Never pass unsanitized HTML strings to `dangerouslySetInnerHTML` unless content is trusted or sanitized with a library like DOMPurify.
User-generated URLs in `href` attributes can enable javascript: protocol attacks — validate URLs before rendering links. Treat all external content as untrusted at the JSX boundary.
- Default escaping prevents XSS
- Avoid dangerouslySetInnerHTML
- Validate user-provided URLs