Skip to main content
React Virtual DOM

Introduction to React

React is a JavaScript library for building user interfaces, developed by Facebook. It allows developers to build reusable UI components and manage the state of their applications efficiently.

Why React?

  1. Component-Based: Build encapsulated components that manage their own state, then compose them to make complex UIs.
  2. Declarative: Design simple views for each state in your application, and React will efficiently update and render just the right components when your data changes.
  3. Virtual DOM: React uses a virtual DOM to improve performance. It calculates the minimal set of changes needed to update the actual DOM.
  4. Ecosystem: A massive ecosystem of libraries, tools, and community support.

How React Works Under the Hood

Understanding what happens behind the scenes helps you write better React code and debug issues effectively.

JSX Transformation

JSX is not valid JavaScript—it needs to be transformed before the browser can execute it. Tools like Babel or SWC (used by Vite) compile JSX into regular JavaScript function calls.
// What you write (JSX)
const element = <h1 className="greeting">Hello, world!</h1>;

// What it compiles to (JavaScript)
const element = React.createElement(
  'h1',                          // tag type
  { className: 'greeting' },     // props object
  'Hello, world!'                // children
);
For nested elements, it creates nested createElement calls:
// JSX
const app = (
  <div>
    <h1>Title</h1>
    <p>Description</p>
  </div>
);

// Compiled JavaScript
const app = React.createElement(
  'div',
  null,
  React.createElement('h1', null, 'Title'),
  React.createElement('p', null, 'Description')
);
Modern React (17+): Uses jsx-runtime instead of React.createElement, which is slightly more efficient and doesn’t require importing React in every file.

The Virtual DOM Explained

The Virtual DOM is a lightweight JavaScript representation of the actual DOM. React uses it to minimize expensive DOM operations.
┌─────────────────────────────────────────────────────────────────┐
│                    React Rendering Pipeline                     │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  1. State/Props Change                                          │
│         │                                                       │
│         ▼                                                       │
│  2. Create New Virtual DOM Tree                                 │
│         │                                                       │
│         ▼                                                       │
│  3. Diffing: Compare Old vs New Virtual DOM                     │
│         │                                                       │
│         ▼                                                       │
│  4. Reconciliation: Calculate Minimal Changes                   │
│         │                                                       │
│         ▼                                                       │
│  5. Batch Update: Apply changes to Real DOM                     │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘
Why is this faster?
Direct DOM ManipulationReact’s Approach
Every change = immediate DOM updateChanges batched together
DOM operations are slow (layout, paint)Virtual DOM operations are fast (JS objects)
May update more than neededOnly updates what changed (diffing)

The Reconciliation Algorithm

React’s diffing algorithm has O(n) complexity through these heuristics:
  1. Different element types → Rebuild entire subtree
  2. Same element type → Update only changed attributes
  3. Lists with keys → Efficiently reorder/update items
// Without keys - React rebuilds all list items
<ul>
  {items.map(item => <li>{item}</li>)}
</ul>

// With keys - React tracks each item individually
<ul>
  {items.map(item => <li key={item.id}>{item.name}</li>)}
</ul>
Performance Tip: Always use stable, unique key props for list items. Using array index as key can cause bugs when list order changes!

Setting Up a React Project

The easiest way to start a new React project is using Vite (recommended) or Create React App.

Using Vite

npm create vite@latest my-react-app -- --template react
cd my-react-app
npm install
npm run dev

JSX (JavaScript XML)

JSX is a syntax extension for JavaScript. It looks like HTML, but it allows you to write HTML structures within JavaScript code.
const element = <h1>Hello, world!</h1>;

Rules of JSX

  1. Return a Single Root Element: You must wrap adjacent elements in a parent tag or a Fragment (<>...</>).
    // Wrong
    return (
      <h1>Header</h1>
      <p>Paragraph</p>
    );
    
    // Correct
    return (
      <>
        <h1>Header</h1>
        <p>Paragraph</p>
      </>
    );
    
  2. Close All Tags: Self-closing tags must end with a slash (e.g., <img />, <br />).
  3. camelCase Properties: HTML attributes become camelCase in JSX.
    • class -> className
    • onclick -> onClick
    • tabindex -> tabIndex
  4. JavaScript Expressions: You can embed any valid JavaScript expression inside curly braces {}.
    const name = "Josh";
    const element = <h1>Hello, {name}</h1>;
    

Conditional Rendering

You can use JavaScript operators like if or the ternary operator inside JSX.

Ternary Operator

const isLoggedIn = true;

return (
  <div>
    {isLoggedIn ? <button>Logout</button> : <button>Login</button>}
  </div>
);

Logical AND (&&)

Render something only if a condition is true:
const hasNotifications = true;
const count = 5;

return (
  <div>
    {hasNotifications && <span className="badge">{count}</span>}
  </div>
);
Gotcha with &&: Avoid using numbers with &&. If count is 0, React will render 0 instead of nothing!
// ❌ Bad - renders "0" when count is 0
{count && <span>{count} items</span>}

// ✅ Good - use explicit boolean check
{count > 0 && <span>{count} items</span>}

Logical OR (||) and Nullish Coalescing (??)

Provide fallback values:
function Greeting({ name }) {
  return <h1>Hello, {name || 'Guest'}!</h1>;
}

// ?? only checks for null/undefined, not falsy values
function Price({ value }) {
  return <span>${value ?? 'N/A'}</span>;
}

Early Returns

For complex conditions, use early returns for cleaner code:
function UserProfile({ user, loading, error }) {
  if (loading) return <LoadingSpinner />;
  if (error) return <ErrorMessage error={error} />;
  if (!user) return <p>No user found</p>;
  
  return (
    <div>
      <h1>{user.name}</h1>
      <p>{user.email}</p>
    </div>
  );
}

Styling in React

React offers multiple ways to style components:

Inline Styles

function Button() {
  const buttonStyle = {
    backgroundColor: 'blue',
    color: 'white',
    padding: '10px 20px',
    borderRadius: '5px',
    border: 'none',
    cursor: 'pointer'
  };

  return <button style={buttonStyle}>Click Me</button>;
}
Inline styles use camelCase property names (backgroundColor not background-color) and values are strings or numbers.

CSS Modules

CSS Modules scope styles locally to the component:
/* Button.module.css */
.button {
  background-color: blue;
  color: white;
}

.button:hover {
  background-color: darkblue;
}
import styles from './Button.module.css';

function Button() {
  return <button className={styles.button}>Click Me</button>;
}

Conditional Classes

function Button({ variant, disabled }) {
  const className = `btn ${variant === 'primary' ? 'btn-primary' : 'btn-secondary'} ${disabled ? 'btn-disabled' : ''}`;
  
  return <button className={className}>Click</button>;
}

// Or use a library like clsx
import clsx from 'clsx';

function Button({ variant, disabled }) {
  return (
    <button className={clsx('btn', {
      'btn-primary': variant === 'primary',
      'btn-secondary': variant === 'secondary',
      'btn-disabled': disabled
    })}>
      Click
    </button>
  );
}

Common JSX Pitfalls

1. Forgetting to Return JSX

// ❌ Wrong - forgot to return
function Greeting() {
  <h1>Hello</h1>;
}

// ✅ Correct - explicit return
function Greeting() {
  return <h1>Hello</h1>;
}

// ✅ Correct - implicit return with parentheses
const Greeting = () => (
  <h1>Hello</h1>
);

2. Using class Instead of className

// ❌ Wrong - class is a reserved word in JavaScript
<div class="container">

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

3. Forgetting to Close Tags

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

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

4. Rendering Objects Directly

const user = { name: 'Alice', age: 25 };

// ❌ Wrong - Objects are not valid as React children
<p>{user}</p>

// ✅ Correct - access specific properties
<p>{user.name}, {user.age}</p>

// ✅ Or stringify it
<pre>{JSON.stringify(user, null, 2)}</pre>

5. Incorrect Boolean Attributes

// ❌ Wrong - this will always be disabled
<button disabled="false">Click</button>

// ✅ Correct - pass boolean value
<button disabled={false}>Click</button>
<button disabled={isDisabled}>Click</button>

🎯 Practice Exercises

Create a ProfileCard component that displays:
  • A profile image
  • Name
  • Bio
  • A “Follow” button
// Your solution
function ProfileCard() {
  const user = {
    name: 'Jane Doe',
    avatar: 'https://via.placeholder.com/100',
    bio: 'Full-stack developer passionate about React'
  };

  return (
    <div className="profile-card">
      <img src={user.avatar} alt={user.name} />
      <h2>{user.name}</h2>
      <p>{user.bio}</p>
      <button>Follow</button>
    </div>
  );
}
Create a component that shows different status badges based on a status prop:
  • “online” → Green badge
  • “away” → Yellow badge
  • “offline” → Gray badge
function StatusBadge({ status }) {
  const colors = {
    online: '#22c55e',
    away: '#eab308',
    offline: '#6b7280'
  };

  const labels = {
    online: 'Online',
    away: 'Away',
    offline: 'Offline'
  };

  return (
    <span style={{
      backgroundColor: colors[status],
      color: 'white',
      padding: '4px 8px',
      borderRadius: '9999px',
      fontSize: '12px'
    }}>
      {labels[status]}
    </span>
  );
}

// Usage
<StatusBadge status="online" />
Given an array of products, render them as a list:
const products = [
  { id: 1, name: 'Laptop', price: 999 },
  { id: 2, name: 'Phone', price: 699 },
  { id: 3, name: 'Tablet', price: 499 }
];

function ProductList() {
  return (
    <ul>
      {products.map(product => (
        <li key={product.id}>
          {product.name} - ${product.price}
        </li>
      ))}
    </ul>
  );
}

Summary

ConceptDescription
ReactJavaScript library for building component-based UIs
Virtual DOMLightweight representation of the DOM for efficient updates
JSXSyntax extension that lets you write HTML-like code in JavaScript
Babel/SWCCompilers that transform JSX into React.createElement calls
ViteModern, fast build tool for React projects
Fragments<>...</> to group elements without adding DOM nodes
ExpressionsUse {} to embed JavaScript in JSX
Conditional RenderingTernary ? :, logical &&, or early returns

Next Steps

In the next chapter, you’ll learn about Components & Props — how to break your UI into reusable pieces and pass data between them.