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

ReactJSX
JavaScript librarySyntax extension
Creating and managing componentsLooks like HTML inside JavaScript
Managing stateIs completely OPTIONAL
Managing lifecycleIs transformed to JavaScript
Implementing Virtual DOMMakes code more readable
Performing reconciliationSupports 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: &lt;script&gt;alert("hack")&lt;/script&gt;

// ❌ 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 expression

Templates (Vue/Angular) - Limitations:

  • Less complexity
  • Less JavaScript power
  • Logic separated from template

JSX (React) - Advantages:

  • Uses JavaScript
  • Flexibility
  • Logic and UI together

Sources

← Back to Blog