What is React and How Does It Work?

React is the “R” in MERN and the technology that controls everything the user sees and interacts with in the browser. It is a JavaScript library for building user interfaces, maintained by Meta (Facebook) and open-source contributors. React’s defining idea is simple but powerful: describe what the UI should look like for a given application state, and let React figure out the minimum set of DOM changes needed to make the browser match that description. This declarative approach โ€” combined with a component model that makes UI pieces reusable โ€” is what makes React so productive for building the kind of dynamic, data-driven interfaces that MERN applications require.

React in the MERN Stack

Layer Technology Responsibility
Database MongoDB Stores application data as documents
API Server Express + Node.js Handles HTTP requests, queries MongoDB, returns JSON
UI Library React Renders the interface, manages UI state, calls the API
Note: React is a library, not a framework. It solves one problem: rendering the right UI for a given state. It does not include a router, an HTTP client, a form library, or a state management solution. These come from the React ecosystem โ€” React Router, Axios, React Hook Form, and React Context or Zustand. This is different from Angular (a full framework) but it is by design: you compose the tools you need rather than accepting a pre-determined architecture.
Tip: For new MERN projects in 2025, scaffold your React frontend with Vite rather than the older Create React App (CRA). Vite starts in under one second regardless of project size, uses native ES modules for instant hot module replacement, and produces smaller, faster production builds. CRA is deprecated and unmaintained. The command is: npm create vite@latest client -- --template react
Warning: React is a browser-based UI library โ€” it runs in the user’s browser, not on your server. This means it has access to the DOM, browser APIs, and localStorage, but it has no direct access to MongoDB or your file system. All data operations must go through your Express API. React fetches data from /api/posts, displays it, and sends changes back to /api/posts โ€” never touching the database directly.

How React Works โ€” The Mental Model

Traditional (Imperative) UI โ€” jQuery / vanilla JS:
  1. User clicks "Load Posts"
  2. You write code: find the list element, clear it, fetch data,
     create new elements, append them one by one
  3. You manually manage every DOM change

React (Declarative) UI:
  1. You describe: "When posts = [...], render a <ul> with one <li> per post"
  2. User clicks "Load Posts" โ†’ state changes to posts = [{ title: '...' }, ...]
  3. React automatically re-renders and updates only the changed DOM nodes
  4. You never touch the DOM directly โ€” React handles it

The Virtual DOM

How React updates the UI efficiently:

Step 1: State changes (e.g. posts array updated with new data)
        โ”‚
        โ–ผ
Step 2: React re-renders the component in memory
        (creates a new Virtual DOM โ€” a lightweight JS object tree)
        โ”‚
        โ–ผ
Step 3: React "diffs" the new Virtual DOM against the previous one
        (finds the exact minimum set of changes needed)
        โ”‚
        โ–ผ
Step 4: React applies ONLY those changes to the real browser DOM
        (e.g. adds 3 new <li> elements โ€” does not rebuild the whole list)
        โ”‚
        โ–ผ
Step 5: Browser paints the changes โ€” user sees the updated UI

Result: Fast, predictable updates even in complex, large UIs

Component-Based Architecture

Every piece of a React UI is a component โ€” a JavaScript function that accepts data (props) and returns JSX describing what to render. Components are composable: you build complex interfaces by nesting simpler components.

// A simple React component โ€” a function that returns JSX
function PostCard({ title, author, createdAt }) {
  return (
    <div className="post-card">
      <h2>{title}</h2>
      <p>By {author} ยท {new Date(createdAt).toLocaleDateString()}</p>
    </div>
  );
}

// Composing components โ€” PostList uses PostCard
function PostList({ posts }) {
  return (
    <ul className="post-list">
      {posts.map(post => (
        <PostCard
          key={post._id}
          title={post.title}
          author={post.author.name}
          createdAt={post.createdAt}
        />
      ))}
    </ul>
  );
}

React vs Other Frontend Approaches

Approach Key Characteristic Learning Curve Best For
Vanilla JS / jQuery Imperative DOM manipulation Low Simple pages, minimal interactivity
React Declarative, component-based, huge ecosystem Medium SPAs, dynamic data-driven UIs, MERN
Angular Full framework โ€” routing, HTTP, DI built in High Large enterprise apps, MEAN stack
Vue Progressive, gentle learning curve Low-Medium Teams transitioning from jQuery, MEVN
Svelte Compiles away at build time โ€” no runtime Low-Medium Performance-critical, smaller bundles

React’s Data Flow

// React data flows DOWN through props, events flow UP through callbacks

// Parent component โ€” owns the state and the data
function BlogPage() {
  const [posts, setPosts] = React.useState([]);
  const [loading, setLoading] = React.useState(true);

  React.useEffect(() => {
    // Fetch posts from the Express API
    fetch('/api/posts')
      .then(res => res.json())
      .then(data => { setPosts(data.data); setLoading(false); });
  }, []);

  const handleDelete = (postId) => {
    // Update local state after deletion โ€” no page reload
    setPosts(prev => prev.filter(p => p._id !== postId));
  };

  if (loading) return <p>Loading...</p>;

  return (
    <div>
      <h1>Blog</h1>
      {posts.map(post => (
        // Data flows DOWN as props
        // Events flow UP as callbacks (onDelete)
        <PostCard key={post._id} post={post} onDelete={handleDelete} />
      ))}
    </div>
  );
}

Common Mistakes

Mistake 1 โ€” Treating React like jQuery (imperative DOM manipulation)

โŒ Wrong โ€” manually touching the DOM inside React components:

function Counter() {
  const handleClick = () => {
    document.getElementById('count').textContent = '1'; // direct DOM manipulation
  };
  return <div><span id="count">0</span><button onClick={handleClick}>+</button></div>;
}

โœ… Correct โ€” use state to describe the desired UI and let React update the DOM:

function Counter() {
  const [count, setCount] = React.useState(0);
  return <div><span>{count}</span><button onClick={() => setCount(c => c + 1)}>+</button></div>;
}

Mistake 2 โ€” Confusing React with Next.js or Remix

โŒ Wrong โ€” expecting React to provide server-side rendering, file-based routing, or API routes out of the box.

โœ… Correct โ€” plain React (via Vite) produces a client-side single-page application. Next.js and Remix are React-based frameworks that add SSR, routing, and server features on top. For this MERN series, plain Vite + React is the right choice โ€” the Express API handles the server side.

Mistake 3 โ€” Calling the API directly from every component

โŒ Wrong โ€” scattered API calls across many components:

// PostCard.jsx โ€” makes its own API call
function PostCard({ postId }) {
  useEffect(() => { fetch(`/api/posts/${postId}`).then(...) }, [postId]);
}

โœ… Correct โ€” centralise API calls in a service layer or a parent component and pass data down as props. Keep components focused on rendering, not data fetching.

Quick Reference

Concept Key Point
Component A function that returns JSX
Props Data passed into a component from its parent
State Data owned and managed by a component โ€” changes trigger re-render
Virtual DOM In-memory representation โ€” React diffs it to minimise real DOM updates
Declarative Describe what the UI should look like โ€” not how to update it step by step
Unidirectional flow Data flows down via props, events flow up via callback functions

🧠 Test Yourself

A developer says “React is a full framework that includes routing, HTTP requests, and state management out of the box.” Is this correct?