05_JSX(syntax extension to JavaScript) - Maniconserve/React-Wiki GitHub Wiki

JSX stands for JavaScript XML. It is a syntax extension to JavaScript that lets you write HTML-like markup directly inside JavaScript code. JSX is not valid JavaScript on its own — it gets compiled by Babel into regular JavaScript before the browser runs it.


🔀 The Evolution: 4 Ways to Render a Heading

To understand why JSX exists, let's render a simple <h1>Hello, World!</h1> four different ways.


1️⃣ Plain HTML — index.html

The traditional way. HTML lives in its own file.

<!DOCTYPE html>
<html>
  <head>
    <title>My App</title>
  </head>
  <body>
    <h1>Hello, World!</h1>
  </body>
</html>

✅ Simple and readable.
❌ Static — you cannot dynamically change content without JavaScript.


2️⃣ Vanilla JavaScript — app.js (using the DOM)

JavaScript manipulates the HTML page by selecting elements and setting their content.

<!-- index.html -->
<body>
  <div id="root"></div>
  <script src="app.js"></script>
</body>
// app.js
const heading = document.createElement('h1');
heading.textContent = 'Hello, World!';

const root = document.getElementById('root'); root.appendChild(heading);

✅ Dynamic — content can change at runtime.
❌ Verbose and hard to manage as your UI grows. You are manually building the DOM piece by piece.


3️⃣ React Without JSX — app.js (using React.createElement)

React provides a JavaScript function to create UI elements. No HTML file syntax needed.

// app.js
import React from 'react';
import ReactDOM from 'react-dom/client';

const heading = React.createElement('h1', null, 'Hello, World!');

const root = ReactDOM.createRoot(document.getElementById('root')); root.render(heading);

React.createElement(type, props, ...children) takes:

  • type — the HTML tag as a string ('h1', 'div', etc.)
  • props — attributes like { className: 'title', id: 'main' }, or null if none
  • children — the content inside the element

✅ Pure JavaScript — no special syntax required.
❌ Very hard to read and write for complex UIs. Deeply nested components become unmanageable quickly.


4️⃣ React With JSX — app.jsx ✅ Recommended

JSX lets you write HTML-like syntax directly in JavaScript. Babel compiles it into React.createElement() calls behind the scenes.

// app.jsx
import React from 'react';
import ReactDOM from 'react-dom/client';

function App() { return <h1>Hello, World!</h1>; }

const root = ReactDOM.createRoot(document.getElementById('root')); root.render(<App />);

Under the hood, Babel transforms <h1>Hello, World!</h1> into:

React.createElement('h1', null, 'Hello, World!')

✅ Readable — looks like HTML, familiar to anyone who knows web development.
✅ Powerful — you can embed JavaScript expressions directly inside your markup.
✅ Industry standard for React development.


🔗 Embedding JavaScript in JSX

Use { } curly braces to inject any JavaScript expression inside JSX.

const name = 'Arjun';
const age = 22;

function App() { return ( <div> <h1>Hello, {name}!</h1> <p>You are {age > 18 ? 'an adult' : 'a minor'}.</p> </div> ); }


⚠️ JSX Limitations & Rules

JSX looks like HTML but it is not HTML. Because JSX is compiled into JavaScript, certain HTML attributes conflict with reserved JavaScript keywords. Here are the key differences:


1. classclassName

Reason: class is a reserved keyword in JavaScript (used to define ES6 classes). Using class as an attribute name inside JSX would confuse the JavaScript parser.

// ❌ Wrong — 'class' is a JS keyword
<h1 class="title">Hello</h1>

// ✅ Correct <h1 className="title">Hello</h1>


2. forhtmlFor

Reason: for is also a reserved keyword in JavaScript (used in for loops). It is renamed in JSX to avoid the conflict.

// ❌ Wrong
<label for="email">Email</label>

// ✅ Correct <label htmlFor="email">Email</label>


3. Must Return a Single Root Element

JSX expressions must have one parent element. You cannot return two sibling elements side by side.

// ❌ Wrong — two root elements
return (
  <h1>Hello</h1>
  <p>Welcome</p>
);

// ✅ Option 1 — wrap in a div return ( <div> <h1>Hello</h1> <p>Welcome</p> </div> );

// ✅ Option 2 — use a Fragment (renders no extra DOM element) return ( <> <h1>Hello</h1> <p>Welcome</p> </> );


4. All Tags Must Be Closed

HTML allows some tags to be left unclosed (e.g., <br>, <img>). JSX requires every tag to be self-closed or explicitly closed.

// ❌ Wrong
<br>
<img src="photo.png">
<input type="text">

// ✅ Correct <br /> <img src="photo.png" /> <input type="text" />


5. camelCase for Event Attributes

HTML event attributes are all lowercase. In JSX they are written in camelCase because JSX maps them to JavaScript DOM event properties.

// ❌ Wrong — HTML style
<button onclick="handleClick()">Click Me</button>

// ✅ Correct — JSX style <button onClick={handleClick}>Click Me</button>

Common examples:

HTML Attribute JSX Equivalent
onclick onClick
onchange onChange
onsubmit onSubmit
onmouseover onMouseOver

🔄 What Babel Does Behind the Scenes

When you write JSX, Babel transforms it before the browser sees it:

You write:

function App() {
  return (
    <div className="container">
      <h1>Hello, {name}</h1>
      <button onClick={handleClick}>Click</button>
    </div>
  );
}

Babel compiles it to:

function App() {
  return React.createElement(
    'div',
    { className: 'container' },
    React.createElement('h1', null, 'Hello, ', name),
    React.createElement('button', { onClick: handleClick }, 'Click')
  );
}

This is exactly why JSX rules exist — the output must be valid JavaScript.


Part of the React Project Wiki — see also: React Project Structure

# JSX — JavaScript Syntax Extension Wiki

JSX stands for JavaScript XML. It is a syntax extension to JavaScript that lets you write HTML-like markup directly inside JavaScript code. JSX is not valid JavaScript on its own — it gets compiled by Babel into regular JavaScript before the browser runs it.


🔀 The Evolution: 4 Ways to Render a Heading

To understand why JSX exists, let's render a simple <h1>Hello, World!</h1> four different ways.


1️⃣ Plain HTML — index.html

The traditional way. HTML lives in its own file.

<!DOCTYPE html>
<html>
  <head>
    <title>My App</title>
  </head>
  <body>
    <h1>Hello, World!</h1>
  </body>
</html>

✅ Simple and readable.
❌ Static — you cannot dynamically change content without JavaScript.


2️⃣ Vanilla JavaScript — app.js (using the DOM)

JavaScript manipulates the HTML page by selecting elements and setting their content.

<!-- index.html -->
<body>
  <div id="root"></div>
  <script src="app.js"></script>
</body>
// app.js
const heading = document.createElement('h1');
heading.textContent = 'Hello, World!';

const root = document.getElementById('root');
root.appendChild(heading);

✅ Dynamic — content can change at runtime.
❌ Verbose and hard to manage as your UI grows. You are manually building the DOM piece by piece.


3️⃣ React Without JSX — app.js (using React.createElement)

React provides a JavaScript function to create UI elements. No HTML file syntax needed.

// app.js
import React from 'react';
import ReactDOM from 'react-dom/client';

const heading = React.createElement('h1', null, 'Hello, World!');

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(heading);

React.createElement(type, props, ...children) takes:

  • type — the HTML tag as a string ('h1', 'div', etc.)
  • props — attributes like { className: 'title', id: 'main' }, or null if none
  • children — the content inside the element

✅ Pure JavaScript — no special syntax required.
❌ Very hard to read and write for complex UIs. Deeply nested components become unmanageable quickly.


4️⃣ React With JSX — app.jsx ✅ Recommended

JSX lets you write HTML-like syntax directly in JavaScript. Babel compiles it into React.createElement() calls behind the scenes.

// app.jsx
import React from 'react';
import ReactDOM from 'react-dom/client';

function App() {
  return <h1>Hello, World!</h1>;
}

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);

Under the hood, Babel transforms <h1>Hello, World!</h1> into:

React.createElement('h1', null, 'Hello, World!')

✅ Readable — looks like HTML, familiar to anyone who knows web development.
✅ Powerful — you can embed JavaScript expressions directly inside your markup.
✅ Industry standard for React development.


🔗 Embedding JavaScript in JSX

Use { } curly braces to inject any JavaScript expression inside JSX.

const name = 'Arjun';
const age = 22;

function App() {
  return (
    <div>
      <h1>Hello, {name}!</h1>
      <p>You are {age > 18 ? 'an adult' : 'a minor'}.</p>
    </div>
  );
}

⚠️ JSX Limitations & Rules

JSX looks like HTML but it is not HTML. Because JSX is compiled into JavaScript, certain HTML attributes conflict with reserved JavaScript keywords. Here are the key differences:


1. classclassName

Reason: class is a reserved keyword in JavaScript (used to define ES6 classes). Using class as an attribute name inside JSX would confuse the JavaScript parser.

// ❌ Wrong — 'class' is a JS keyword
<h1 class="title">Hello</h1>

// ✅ Correct
<h1 className="title">Hello</h1>

2. forhtmlFor

Reason: for is also a reserved keyword in JavaScript (used in for loops). It is renamed in JSX to avoid the conflict.

// ❌ Wrong
<label for="email">Email</label>

// ✅ Correct
<label htmlFor="email">Email</label>

3. Must Return a Single Root Element

JSX expressions must have one parent element. You cannot return two sibling elements side by side.

// ❌ Wrong — two root elements
return (
  <h1>Hello</h1>
  <p>Welcome</p>
);

// ✅ Option 1 — wrap in a div
return (
  <div>
    <h1>Hello</h1>
    <p>Welcome</p>
  </div>
);

// ✅ Option 2 — use a Fragment (renders no extra DOM element)
return (
  <>
    <h1>Hello</h1>
    <p>Welcome</p>
  </>
);

4. All Tags Must Be Closed

HTML allows some tags to be left unclosed (e.g., <br>, <img>). JSX requires every tag to be self-closed or explicitly closed.

// ❌ Wrong
<br>
<img src="photo.png">
<input type="text">

// ✅ Correct
<br />
<img src="photo.png" />
<input type="text" />

5. camelCase for Event Attributes

HTML event attributes are all lowercase. In JSX they are written in camelCase because JSX maps them to JavaScript DOM event properties.

// ❌ Wrong — HTML style
<button onclick="handleClick()">Click Me</button>

// ✅ Correct — JSX style
<button onClick={handleClick}>Click Me</button>

Common examples:

HTML Attribute JSX Equivalent
onclick onClick
onchange onChange
onsubmit onSubmit
onmouseover onMouseOver

6. Inline Styles Use Objects, Not Strings

In HTML, inline styles are written as a CSS string. In JSX, they must be written as a JavaScript object with camelCased property names.

// ❌ Wrong — HTML string style
<h1 style="color: red; font-size: 24px;">Hello</h1>

// ✅ Correct — JavaScript object
<h1 style={{ color: 'red', fontSize: '24px' }}>Hello</h1>

The outer { } injects JavaScript into JSX. The inner { } is the object literal.


🧠 Quick Reference: HTML vs JSX

HTML JSX Reason for Change
class className class is a reserved JS keyword
for htmlFor for is a reserved JS keyword
onclick onClick JSX uses camelCase DOM properties
style="color:red" style={{ color: 'red' }} Styles must be JS objects in JSX
<br> <br /> All tags must be closed in JSX
Multiple root elements Single root / Fragment JSX compiles to one function call

🔄 What Babel Does Behind the Scenes

When you write JSX, Babel transforms it before the browser sees it:

You write:

function App() {
  return (
    <div className="container">
      <h1>Hello, {name}</h1>
      <button onClick={handleClick}>Click</button>
    </div>
  );
}

Babel compiles it to:

function App() {
  return React.createElement(
    'div',
    { className: 'container' },
    React.createElement('h1', null, 'Hello, ', name),
    React.createElement('button', { onClick: handleClick }, 'Click')
  );
}

This is exactly why JSX rules exist — the output must be valid JavaScript.


⚠️ **GitHub.com Fallback** ⚠️