Understanding React Step -1 - JSX
What JSX is, how it works and why it is used in React. Learn the difference between JSX and React, and how code is transformed.
JSX and React?
It’s important to understand that JSX is not React, and React is not JSX. This is a common confusion that needs to be clarified from the start.
JSX was created by Facebook in 2013, along with React. It had precedents, possible inspirations and competitors at the time:
- E4X (ECMAScript for XML) - 2004 JavaScript extension that allowed native XML in code
- MXML (Adobe Flex) - XML language for creating Flash/ActionScript interfaces
- String templates - Libraries like Handlebars, Mustache used strings for templates
In 2011-2012, Facebook faced performance and maintainability issues with their UI. Jordan Walke, a Facebook engineer, started experimenting:
// Problem: Imperative code hard to maintain
$('#button').click(function() {
$('#message').text('Clicked!');
$('#counter').text(parseInt($('#counter').text()) + 1);
});
// Solution: Declarative UI
<Button onClick={() => {
setMessage('Clicked!');
setCounter(counter + 1);
}} />
Initial controversy (2013-2014):
When React was presented at JSConf US 2013, the community reacted negatively:
- ❌ “Mixing HTML and JavaScript is a bad practice!”
- ❌ “Violates separation of concerns!”
- ❌ “Looks like 90s code (inline PHP)!”
- ❌ “XML in JavaScript? This is E4X again?”
Over time, advantages stood out such as:
- ✅ Components encapsulate logic AND presentation
- ✅ Easier to understand data flow
- ✅ Errors caught at compile time
- ✅ Safer refactoring
Evolution (2014-2025):
// 2013: Basic JSX
React.createClass({
render: function() {
return <div>Hello {this.props.name}</div>;
}
});
// 2015: ES6 Classes
class Hello extends React.Component {
render() {
return <div>Hello {this.props.name}</div>;
}
}
// 2019: Hooks + JSX
function Hello({ name }) {
return <div>Hello {name}</div>;
}
// 2020+: React 17 - New JSX Transform
// No longer needs: import React from 'react'
function Hello({ name }) {
return <div>Hello {name}</div>; // Works!
}
JSX vs React
| React | JSX |
|---|---|
| JavaScript library | Syntax extension |
| Creating and managing components | Looks like HTML inside JavaScript |
| Managing state | Is completely OPTIONAL |
| Managing lifecycle | Is transformed to JavaScript |
| Implementing Virtual DOM | Makes code more readable |
| Performing reconciliation | Supports JavaScript expressions |
How JSX Works
JSX is transformed into pure JavaScript code by Babel (or another compiler). See the process:
You Write (JSX)
Babel Transforms (JavaScript)
// JSX: Familiar and readable syntax
const element = (
<div className="container">
<h1>Hello, {name}!</h1>
<p>Welcome to React</p>
</div>
);Looks like HTML, but it’s JavaScript in disguise!
// Pure JavaScript: How React actually sees it
const element = React.createElement(
'div',
{ className: 'container' },
React.createElement('h1', null, 'Hello, ', name, '!'),
React.createElement('p', null, 'Welcome to React')
);Nested function calls.
Step-by-Step Transformation
// JSX is read
<button onClick={handleClick}>Click here</button>
// Babel transforms to
React.createElement('button', { onClick: handleClick }, 'Click here')
// 3. React.createElement returns an object
{
type: 'button',
props: {
onClick: handleClick,
children: 'Click here'
},
key: null,
ref: null
}
// 4. React uses this object to create the DOM element
<button>Click here</button>
Why Use JSX?
function TodoList({ todos }) {
return React.createElement(
'div',
{ className: 'todo-container' },
React.createElement(
'h2',
null,
'My Tasks'
),
React.createElement(
'ul',
{ className: 'todo-list' },
todos.map(todo =>
React.createElement(
'li',
{
key: todo.id,
className: todo.completed ? 'completed' : ''
},
React.createElement(
'input',
{
type: 'checkbox',
checked: todo.completed,
onChange: () => toggleTodo(todo.id)
}
),
React.createElement('span', null, todo.text)
)
)
)
);
}function TodoList({ todos }) {
return (
<div className="todo-container">
<h2>My Tasks</h2>
<ul className="todo-list">
{todos.map(todo => (
<li
key={todo.id}
className={todo.completed ? 'completed' : ''}
>
<input
type="checkbox"
checked={todo.completed}
onChange={() => toggleTodo(todo.id)}
/>
<span>{todo.text}</span>
</li>
))}
</ul>
</div>
);
}Without JSX - Problems:
- Hard to read and understand structure
- Too many parentheses and commas
- Easy to make syntax errors
- Difficult to maintain
With JSX - Advantages:
- Clear and visual structure
- Looks like familiar HTML
- Easy to read and maintain
- Less error-prone
Benefits of JSX
1. Readability
<Card title="React" description="JavaScript Library" />
React.createElement(Card, { title: "React", description: "JavaScript Library" })
2. Security (Prevents XSS)
const userInput = '<script>alert("hack")</script>';
// ✅ JSX escapes automatically
<div>{userInput}</div>
// Renders: <script>alert("hack")</script>
// ❌ Dangerous (don't use!)
<div dangerouslySetInnerHTML={{ __html: userInput }} />
4. JavaScript Expressions
// ✅ Any JS expression inside {}
<div>
{/* Variables */}
<h1>{title}</h1>
{/* Operations */}
<p>Price: ${price * 1.1}</p>
{/* Conditionals */}
{isLoggedIn ? <Dashboard /> : <Login />}
{/* Loops */}
{items.map(item => <Item key={item.id} {...item} />)}
{/* Functions */}
<button onClick={() => setCount(count + 1)}>
Clicks: {count}
</button>
</div>
JSX Rules
1. Single Root Element
// ❌ WRONG: Multiple root elements
function Component() {
return (
<h1>Title</h1>
<p>Paragraph</p>
);
}
// ✅ CORRECT: Wrap in an element
function Component() {
return (
<div>
<h1>Title</h1>
<p>Paragraph</p>
</div>
);
}
// ✅ CORRECT: Use Fragment (doesn't create extra DOM element)
function Component() {
return (
<>
<h1>Title</h1>
<p>Paragraph</p>
</>
);
}
2. Close All Tags
// ❌ WRONG: Unclosed tags
<img src="logo.png">
<input type="text">
// ✅ CORRECT: Self-close tags without children
<img src="logo.png" />
<input type="text" />
3. className instead of class
// ❌ WRONG: 'class' is a reserved word in JS
<div class="container">
// ✅ CORRECT: Use 'className'
<div className="container">
4. camelCase Properties
// ❌ Traditional HTML
<div onclick="handleClick()" tabindex="0">
// ✅ JSX in camelCase
<div onClick={handleClick} tabIndex={0}>
JSX vs Templates
Templates (Vue, Angular)
JSX (React)
<!-- Vue/Angular: Special syntax -->
<div v-if="isVisible">
<p v-for="item in items">
{{ item.name }}
</p>
</div>
<!-- Special directives -->
- v-if, v-for, v-bind
- *ngIf, *ngFor
- Custom template language// React: Pure JavaScript
<div>
{isVisible && (
items.map(item => (
<p key={item.id}>{item.name}</p>
))
)}
</div>
// Just JavaScript
- Native if/else
- map/filter/reduce
- Any JS expressionTemplates (Vue/Angular) - Limitations:
- Less complexity
- Less JavaScript power
- Logic separated from template
JSX (React) - Advantages:
- Uses JavaScript
- Flexibility
- Logic and UI together