Suggest an editImprove this articleRefine the answer for “What is JSX in React?”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**JSX** is a syntax extension for JavaScript that lets you write HTML-like markup in JS files. Babel converts it to `React.createElement` calls at build time. ```jsx // JSX const elem = <h1 className="title">Hello, {name}!</h1>; // Compiles to: const elem = React.createElement('h1', { className: 'title' }, 'Hello, ', name, '!'); ``` **Key point:** JSX is syntactic sugar over `React.createElement`. The output is identical either way.Shown above the full answer for quick recall.Answer (EN)Image**JSX** is a syntax extension for JavaScript that lets you write HTML-like markup directly in JS files, which Babel then converts into `React.createElement` calls. ## Theory ### TL;DR - JSX is HTML-shaped syntax inside JavaScript: familiar tags, but expressions go in `{}` - Main win: `<div>Hello</div>` instead of `React.createElement('div', null, 'Hello')` - Babel converts JSX at build time, so there is no runtime overhead - Use JSX in every React component; skip it only when you have no bundler at all - JSX is not HTML: attributes use camelCase (`className`, `onClick`, `htmlFor`) ### Quick example ```jsx // Without JSX (verbose) const elem = React.createElement('h1', null, 'Hello, ', name, '!'); // With JSX (readable) const elem = <h1>Hello, {name}!</h1>; // Babel turns the JSX line into the createElement call above. // Identical output, less code. ``` Curly braces `{}` mark the switch from markup to JavaScript. Everything inside is a JS expression: variables, ternaries, function calls. Plain text outside the braces stays as literal text. ### Key difference from plain HTML JSX looks like HTML but differs in three ways. Attributes are camelCase (`className` not `class`, `htmlFor` not `for`). Every tag must close, including void elements (`<img />`). And you can only return one root element. That third rule is why `<>...</>` (React.Fragment) exists - it wraps sibling elements without adding a real node to the DOM. ### When to use - Any React component → always JSX, no exceptions - Rendering dynamic lists → `{todos.map(todo => <li key={todo.id}>{todo.text}</li>)}` - Conditional output → `{isLoading ? <Spinner /> : <Content />}` - No bundler (CDN React via script tag) → fall back to `React.createElement` directly - Server-side rendering → JSX works fine in Node via `ReactDOMServer.renderToString` ### How Babel handles it Babel's `@babel/preset-react` plugin parses JSX at build time. Uppercase tag names like `<TodoList />` become variable references - your component function. Lowercase names like `<ul>` become string literals. Babel also auto-escapes content, so JSX expressions never inject raw HTML. That prevents XSS by default. The only way around it is `dangerouslySetInnerHTML`, which is intentionally awkward to type. ### Common mistakes **Using `if` statements inside JSX** ```jsx // Wrong - if is a statement, not an expression return <div>{if (isLoggedIn) <p>Hi</p>}</div>; // parse error // Fix - ternary works because it is an expression return <div>{isLoggedIn ? <p>Hi</p> : null}</div>; ``` **Rendering an array of objects without mapping** ```jsx // Wrong - shows "[object Object],[object Object]" <ul>{[{name: 'Alice'}, {name: 'Bob'}]}</ul> // Fix <ul>{[{name: 'Alice'}, {name: 'Bob'}].map(item => <li>{item.name}</li>)}</ul> ``` **Multiple root elements without a Fragment** ```jsx // Wrong - two siblings at the top level return ( <h1>Title</h1> <p>Text</p> ); // syntax error // Fix return ( <> <h1>Title</h1> <p>Text</p> </> ); ``` **`class` instead of `className`** ```jsx // Wrong - class is a reserved keyword in JS <div class="container">Content</div> // Fix <div className="container">Content</div> ``` ### Real-world usage - Next.js: every file in `pages/` or `app/` exports a JSX component - React Native: same JSX syntax, different tags (`<View>`, `<Text>` instead of `<div>`, `<p>`) - Remix, Gatsby: server-rendered JSX with the same mental model - Preact: JSX-compatible drop-in with a 3KB runtime ### Follow-up questions **Q:** What does Babel do to JSX? **A:** It converts every JSX tag to a `React.createElement` call. `<h1>Hi</h1>` becomes `React.createElement("h1", null, "Hi")`. The result is a plain JavaScript object describing the element type and its props. **Q:** Why use curly braces for expressions? **A:** They signal "JavaScript mode here." `{2 + 2}` renders 4. Without them, `2 + 2` stays as the literal string "2 + 2". **Q:** Can JSX return multiple root elements? **A:** No. Wrap them in `<>...</>` (React.Fragment). Fragment elements never appear in the real DOM. **Q:** What is the difference between JSX and HTML attributes? **A:** JSX uses `className` instead of `class`, `htmlFor` instead of `for`, and camelCase event handlers (`onClick` not `onclick`). Attribute names in JSX are case-sensitive; in HTML they are not. **Q:** (Senior) How does JSX handle spread props, and what happens when keys conflict? **A:** `<MyComp {...props} color="blue" />` compiles to `React.createElement(MyComp, Object.assign({}, props, { color: "blue" }))`. Later props override earlier ones. If `props.color` is `"red"`, the final value is `"blue"`. The merge is shallow. ## Examples ### Basic: from JSX to the DOM ```jsx function Greeting({ name }) { return <h1 className="title">Hello, {name}!</h1>; } // Babel compiles the return to: // React.createElement('h1', { className: 'title' }, 'Hello, ', name, '!') // Usage: <Greeting name="Alice" /> // Renders: <h1 class="title">Hello, Alice!</h1> ``` You write JSX, Babel does the conversion, React builds the DOM node. Nothing else is happening. ### Intermediate: dynamic list with conditional styling ```jsx function TodoList({ todos }) { return ( <ul> {todos.map(todo => ( <li key={todo.id} className={todo.completed ? 'done' : ''}> {todo.text} </li> ))} </ul> ); } // Usage: // <TodoList todos={[{ id: 1, text: 'Buy milk', completed: true }]} /> // Output: <ul><li class="done">Buy milk</li></ul> ``` The `key` prop is required when rendering lists. React uses it to track which items changed between renders. Drop it and you get a warning in the console on every update.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.