Understanding JSX syntax and how it transforms to React elements
JSX is a syntax extension for JavaScript that lets you write HTML-like markup inside JavaScript files. While not required for React, JSX makes component code more readable and expressive.
Under the hood, JSX elements are transformed into ReactElement objects using React’s JSX runtime. The modern JSX transform (introduced in React 17) uses jsx() and jsxs() functions:
JSX
Compiled (Modern)
Compiled (Classic)
Copy
Ask AI
<div className="container"><h1>Hello</h1><p>Welcome to React</p></div>
Copy
Ask AI
import { jsx, jsxs } from 'react/jsx-runtime';jsxs('div', {className: 'container',children: [jsx('h1', { children: 'Hello' }),jsx('p', { children: 'Welcome to React' })]});
Copy
Ask AI
import React from 'react';React.createElement('div',{ className: 'container' },React.createElement('h1', null, 'Hello'),React.createElement('p', null, 'Welcome to React'));
The modern JSX transform (using jsx() and jsxs()) was introduced in React 17 and has several advantages:
When JSX is compiled, it creates a ReactElement - a plain JavaScript object that describes what you want to see on the screen:
Copy
Ask AI
// Simplified ReactElement structureconst element = { // Identifies this as a React element $$typeof: Symbol.for('react.transitional.element'), // The type of element (string for DOM, function/class for components) type: 'h1', // The key for reconciliation (if provided) key: null, // The props including children props: { children: 'Hello, world!' }};
React elements are immutable. Once created, you can’t change their props or children. To update the UI, you create a new element and pass it to the renderer.
The key prop is special and is not passed to your component as a prop. If you need the same value in your component, pass it explicitly with a different name:
Because JSX compiles to function calls, it can be used anywhere JavaScript expressions can be used:
Copy
Ask AI
// Return from functionsfunction getGreeting(user) { if (user) { return <h1>Hello, {user.name}!</h1>; } return <h1>Hello, Stranger.</h1>;}// Assign to variablesconst element = <h1>Hello!</h1>;// Store in arraysconst elements = [ <h1 key="1">First</h1>, <h2 key="2">Second</h2>];// Pass as argumentsfunction render(element) { root.render(element);}render(<App />);
// Self-closing tags for empty elements<img src="photo.jpg" />// Opening and closing tags for elements with children<div> <h1>Title</h1> <p>Description</p></div>
React DOM escapes any values embedded in JSX before rendering them, preventing XSS (cross-site-scripting) attacks:
Copy
Ask AI
const userInput = '<script>alert("XSS")</script>';// This is safe - the string will be escapedconst element = <div>{userInput}</div>;// Renders: <div><script>alert("XSS")</script></div>
Everything in JSX is converted to a string before being rendered, so you can never inject anything that’s not explicitly written in your application.