reactjs
/

React JSX – JavaScript XML Deep Dive

Last Sync: Today

On this page

12
0%
5 min read
Remaining
5 minleft

Click any section to jump — progress syncs automatically

reactjs

React JSX – JavaScript XML Deep Dive

What is JSX?

JSX (JavaScript XML) is a syntax extension for JavaScript that allows you to write HTML-like code directly in JavaScript. It makes React code more readable and expressive. JSX gets compiled to regular JavaScript function calls using React.createElement.

JSX Basics

React JSXRead-only
1
// JSX syntax
const element = <h1 className="greeting">Hello, world!</h1>;

// Compiled to
const element = React.createElement('h1', { className: 'greeting' }, 'Hello, world!');

// Multiple elements must be wrapped
const app = (
  <div>
    <h1>Title</h1>
    <p>Paragraph</p>
  </div>
);

// Self-closing tags
const img = <img src="image.jpg" alt="Description" />;
const input = <input type="text" placeholder="Enter name" />;

// Empty tags
const fragment = <></>;
const br = <br />;

JSX Expressions

React JSXRead-only
1
function Greeting({ user, items }) {
  const name = 'John';
  const age = 25;
  
  return (
    <div>
      {/* Embedding JavaScript expressions with curly braces */}
      <h1>Hello, {name}!</h1>
      <p>Age: {age}</p>
      
      {/* Expressions can be any valid JavaScript */}
      <p>Next year you'll be {age + 1}</p>
      <p>Uppercase: {name.toUpperCase()}</p>
      <p>Condition: {age >= 18 ? 'Adult' : 'Minor'}</p>
      
      {/* Function calls */}
      <p>Formatted: {formatDate(new Date())}</p>
      
      {/* Object properties */}
      <p>User: {user?.name ?? 'Guest'}</p>
      
      {/* Arrays are joined */}
      <p>Items: {['apple', 'banana', 'orange']}</p>
      
      {/* Numbers and strings work */}
      <p>{42}</p>
      <p>{'string literal'}</p>
      
      {/* null, undefined, false are ignored */}
      <p>{null}</p>
      <p>{undefined}</p>
      <p>{false}</p>
    </div>
  );
}

JSX Attributes

React JSXRead-only
1
// HTML attributes use camelCase
const button = <button className="btn" onClick={handleClick}>Click</button>;
const input = <input type="text" maxLength={10} readOnly />;
const label = <label htmlFor="name">Name:</label>;

// Special attributes
const svg = <svg viewBox="0 0 100 100"><circle cx="50" cy="50" r="40" /></svg>;

// Boolean attributes (can omit value)
const checkbox = <input type="checkbox" checked={isChecked} />;
const disabled = <button disabled={isDisabled}>Submit</button>;

// Spread attributes
const props = { className: "btn", type: "button", onClick: handleClick };
const spreadButton = <button {...props}>Click</button>;

// Custom attributes (data-* attributes)
const custom = <div data-id="123" data-custom-attribute="value">Content</div>;

// Inline styles (camelCase, object)
const styleButton = (
  <button style={{
    backgroundColor: 'blue',
    color: 'white',
    padding: '10px 20px',
    borderRadius: '4px',
    fontSize: '16px'
  }}>
    Styled Button
  </button>
);

// Dynamic styles
const dynamicStyle = {
  color: isActive ? 'green' : 'red',
  fontWeight: isBold ? 'bold' : 'normal'
};
<p style={dynamicStyle}>Dynamic text</p>

Conditional Rendering in JSX

React JSXRead-only
1
function ConditionalRender({ isLoggedIn, user, items, error }) {
  // 1. If-else outside JSX
  if (error) {
    return <ErrorMessage error={error} />;
  }
  
  if (!items.length) {
    return <EmptyState />;
  }
  
  // 2. Ternary operator
  return (
    <div>
      <h1>Welcome</h1>
      {isLoggedIn ? (
        <UserDashboard user={user} />
      ) : (
        <LoginButton />
      )}
      
      {/* 3. Logical && operator */}
      {isLoggedIn && <WelcomeMessage user={user} />}
      {items.length > 0 && <ItemList items={items} />}
      
      {/* 4. IIFE for complex logic */}
      {(() => {
        if (isLoggedIn && user.isAdmin) {
          return <AdminPanel />;
        } else if (isLoggedIn) {
          return <UserPanel />;
        }
        return <GuestPanel />;
      })()}
      
      {/* 5. Variable assignment */}
      {(() => {
        let content;
        if (isLoggedIn) {
          content = <Profile user={user} />;
        } else {
          content = <LoginForm />;
        }
        return content;
      })()}
    </div>
  );
}

Rendering Lists

React JSXRead-only
1
function TodoList({ todos, categories }) {
  // Basic list rendering
  return (
    <ul>
      {todos.map(todo => (
        <li key={todo.id}>
          {todo.text}
        </li>
      ))}
    </ul>
  );
  
  // List with conditional rendering
  return (
    <div>
      {todos.map(todo => (
        <div key={todo.id} className={todo.completed ? 'completed' : 'active'}>
          <input type="checkbox" checked={todo.completed} readOnly />
          <span>{todo.text}</span>
          {todo.priority === 'high' && <span className="badge">High Priority</span>}
        </div>
      ))}
    </div>
  );
  
  // Filtered list
  const activeTodos = todos.filter(todo => !todo.completed);
  return (
    <ul>
      {activeTodos.map(todo => (
        <li key={todo.id}>{todo.text}</li>
      ))}
    </ul>
  );
  
  // Map with index (use only for static lists)
  return (
    <ul>
      {categories.map((category, index) => (
        <li key={index}>{category}</li>
      ))}
    </ul>
  );
  
  // Nested lists
  return (
    <div>
      {categories.map(category => (
        <div key={category.id}>
          <h3>{category.name}</h3>
          <ul>
            {category.items.map(item => (
              <li key={item.id}>{item.name}</li>
            ))}
          </ul>
        </div>
      ))}
    </div>
  );
}

Fragments

React JSXRead-only
1
// Problem: Adjacent JSX elements must be wrapped
function WithoutFragment() {
  return (
    <div>  {/* Unnecessary div */}
      <h1>Title</h1>
      <p>Content</p>
    </div>
  );
}

// Solution 1: React Fragment (explicit)
import { Fragment } from 'react';

function WithFragment() {
  return (
    <Fragment>
      <h1>Title</h1>
      <p>Content</p>
    </Fragment>
  );
}

// Solution 2: Short syntax (<> </>)
function WithShortFragment() {
  return (
    <>
      <h1>Title</h1>
      <p>Content</p>
    </>
  );
}

// Fragment with key (for mapping)
function FragmentList({ items }) {
  return (
    <dl>
      {items.map(item => (
        <Fragment key={item.id}>
          <dt>{item.term}</dt>
          <dd>{item.description}</dd>
        </Fragment>
      ))}
    </dl>
  );
}

// Fragment with children pattern
function Table({ data }) {
  return (
    <table>
      <tbody>
        {data.map(row => (
          <Fragment key={row.id}>
            {row.cells.map(cell => (
              <tr key={cell.id}>
                <td>{cell.value}</td>
              </tr>
            ))}
          </Fragment>
        ))}
      </tbody>
    </table>
  );
}

JSX Children

React JSXRead-only
1
function Card({ children, header, footer }) {
  return (
    <div className="card">
      {header && <div className="card-header">{header}</div>}
      <div className="card-body">{children}</div>
      {footer && <div className="card-footer">{footer}</div>}
    </div>
  );
}

// String literal children
<div>Hello World</div>

// JSX children
<div>
  <h1>Title</h1>
  <p>Content</p>
</div>

// Expression children
<div>{user.name}</div>

// Function as children (render props)
<DataProvider>
  {(data) => <Display data={data} />}
</DataProvider>

// Multiple children types
<Container>
  <Header />
  {content}
  <Footer />
  {isLoading && <Spinner />}
</Container>

// Children manipulation
export function List({ children, separator }) {
  const array = React.Children.toArray(children);
  return (
    <div>
      {array.map((child, index) => (
        <React.Fragment key={index}>
          {child}
          {index < array.length - 1 && separator}
        </React.Fragment>
      ))}
    </div>
  );
}

// Usage
<List separator={<hr />}>
  <div>Item 1</div>
  <div>Item 2</div>
  <div>Item 3</div>
</List>

JSX Gotchas & Common Mistakes

React JSXRead-only
1
// ❌ Wrong: class instead of className
<div class="container">Content</div>

// ✅ Correct
<div className="container">Content</div>

// ❌ Wrong: for instead of htmlFor
<label for="name">Name:</label>

// ✅ Correct
<label htmlFor="name">Name:</label>

// ❌ Wrong: inline style as string
<div style="color: red">Text</div>

// ✅ Correct
<div style={{ color: 'red' }}>Text</div>

// ❌ Wrong: comments in JSX
<div>
  // This is a comment
  <p>Text</p>
</div>

// ✅ Correct
<div>
  {/* This is a comment */}
  <p>Text</p>
</div>

// ❌ Wrong: if statements inside JSX
<div>
  {if (condition) { <p>True</p> }}
</div>

// ✅ Correct: ternary or &&
<div>
  {condition ? <p>True</p> : <p>False</p>}
</div>

// ❌ Wrong: multiple root elements
return (
  <h1>Title</h1>
  <p>Content</p>
);

// ✅ Correct: wrap with fragment
return (
  <>
    <h1>Title</h1>
    <p>Content</p>
  </>
);

// ❌ Wrong: reserved words
<div {...props}></div> // 'for', 'class' not allowed

// ❌ Wrong: unescaped entities
<div>&copy; 2024</div> // Works but not recommended

// ✅ Correct: use dangerouslySetInnerHTML or literal
<div>© 2024</div>
<div dangerouslySetInnerHTML={{ __html: '&copy; 2024' }} />

JSX Best Practices

  • Use parentheses for multi-line JSX – Improves readability
  • Keep expressions simple – Extract complex logic outside JSX
  • Use fragments to avoid extra DOM nodes – Reduces nesting
  • Always add keys when mapping – Helps React identify items
  • Use camelCase for all HTML attributes – Consistent with React
  • Self-close tags with no children – Cleaner syntax
  • Use template literals for dynamic strings – Instead of concatenation
  • Extract repeated JSX into components – DRY principle
  • Use boolean attributes without values – Cleaner when true
  • Avoid inline functions in render – Extract to handlers

JSX Transformations (React 17+)

React JSXRead-only
1
// Modern JSX transform (React 17+)
// No need to import React
function App() {
  return <h1>Hello World</h1>;
}

// Compiles to
import { jsx as _jsx } from 'react/jsx-runtime';
function App() {
  return _jsx('h1', { children: 'Hello World' });
}

// Classic transform (before React 17)
import React from 'react';
function App() {
  return <h1>Hello World</h1>;
}

// Compiles to
import React from 'react';
function App() {
  return React.createElement('h1', null, 'Hello World');
}

// Configuration in tsconfig.json
{
  "compilerOptions": {
    "jsx": "react-jsx"  // Modern transform
    // "jsx": "react"   // Classic transform
  }
}

Conclusion

JSX is a powerful syntax extension that makes React code more readable and maintainable. It combines the power of JavaScript with the familiarity of HTML. Understanding JSX fundamentals, expressions, conditional rendering, and common patterns is essential for effective React development.

Try it yourself

import { useState } from 'react';

// JSX Demo Component
function JSXDemonstration() {
  const [count, setCount] = useState(0);
  const [isVisible, setIsVisible] = useState(true);
  const items = ['Apple', 'Banana', 'Orange', 'Grape'];
  const user = { name: 'John', age: 25, isAdmin: true };

  // JSX expressions, conditionals, and lists
  return (
    <div style={{ padding: '20px', fontFamily: 'Arial' }}>
      <h1>JSX Features Demo</h1>
      
      {/* Expressions */}
      <div className="demo-section">
        <h2>1. JavaScript Expressions</h2>
        <p>Hello, {user.name}!</p>
        <p>You are {user.age} years old</p>
        <p>Next year you'll be {user.age + 1}</p>
        <p>Uppercase name: {user.name.toUpperCase()}</p>
      </div>

      {/* Conditional Rendering */}
      <div className="demo-section">
        <h2>2. Conditional Rendering</h2>
        <button onClick={() => setIsVisible(!isVisible)}>
          Toggle Content
        </button>
        
        {/* Ternary operator */}
        {isVisible ? (
          <div style={{ marginTop: '10px', padding: '10px', background: '#f0f0f0' }}>
            This content is visible!
          </div>
        ) : (
          <div style={{ marginTop: '10px', padding: '10px', background: '#e0e0e0' }}>
            This content is hidden
          </div>
        )}
        
        {/* Logical && operator */}
        {user.isAdmin && (
          <div style={{ marginTop: '10px', color: 'blue' }}>
            ⭐ Admin privileges active
          </div>
        )}
      </div>

      {/* Lists and Keys */}
      <div className="demo-section">
        <h2>3. Rendering Lists</h2>
        <ul>
          {items.map((item, index) => (
            <li key={index}>
              {item}
            </li>
          ))}
        </ul>
      </div>

      {/* Events and State */}
      <div className="demo-section">
        <h2>4. Events and State</h2>
        <p>Count: {count}</p>
        <button onClick={() => setCount(count + 1)}>
          Increment
        </button>
        <button onClick={() => setCount(count - 1)} style={{ marginLeft: '10px' }}>
          Decrement
        </button>
        <button onClick={() => setCount(0)} style={{ marginLeft: '10px' }}>
          Reset
        </button>
      </div>

      {/* Inline Styles */}
      <div className="demo-section">
        <h2>5. Inline Styles</h2>
        <div style={{
          backgroundColor: '#4CAF50',
          color: 'white',
          padding: '10px',
          borderRadius: '4px',
          textAlign: 'center'
        }}>
          Styled with JSX inline styles
        </div>
      </div>

      {/* Fragments Example */}
      <div className="demo-section">
        <h2>6. Fragments (no extra div)</h2>
        <>
          <p>This</p>
          <p>is</p>
          <p>wrapped</p>
          <p>in a fragment</p>
        </>
      </div>
    </div>
  );
}

export default JSXDemonstration;

Test Your Knowledge

Q1
of 4

What is the correct way to add a CSS class in JSX?

A
class
B
cssClass
C
className
D
classname
Q2
of 4

How do you embed JavaScript expressions in JSX?

A
${expression}
B
{{expression}}
C
{expression}
D
[expression]
Q3
of 4

What fragment syntax was introduced in React 16.2?

A
<fragment>
B
<React.Fragment>
C
<> </>
D
<div>
Q4
of 4

What is the correct way to write inline styles in JSX?

A
style="color: red"
B
style={{ color: 'red' }}
C
style={color: 'red'}
D
styles={{ color: 'red' }}

Frequently Asked Questions

What does JSX stand for?

JavaScript XML - a syntax extension for JavaScript.

Is JSX required for React?

No, you can use React.createElement directly, but JSX is recommended.

Why className instead of class?

class is a reserved word in JavaScript, so React uses className.

Can browsers understand JSX?

No, JSX must be compiled to JavaScript using Babel or TypeScript.

Previous

react setup

Next

react components

Related Content

Need help?

Explore our comprehensive docs or start a chat with our tech experts.