DeepFrontend
Practice ArenaBlogSign in
Go Pro
DeepFrontend

Interview-grade learning paths and hands-on practice for mid-to-senior engineers. Master internals, patterns, and system architecture with runnable code.

All systems operational

Core Courses

  • -JavaScript Internals
  • -React Reconciliation
  • -TypeScript rigor
  • -Next.js Caching
  • -Node.js Event Loop
  • -System Design
  • -Web Security
  • -CSS & Page Layouts

Explore

  • Learning Paths
  • Practice Arena
  • Pricing Options
  • HTML Sitemap

Resources

  • Privacy Policy
  • Terms of Service
  • Email Support

© 2026 DeepFrontend. All rights reserved.

Expert learning environments for web engineering teams.

Home/React/Components
beginner20 min read·Updated Jun 2025

Components

A React component is just a function that returns a description of UI — not the UI itself. Everything else in React (props, state, re-renders, composition) is a consequence of that one fact.

componentscompositionfunction-componentsfundamentals

Knowledge Check

4 questions · pass at 70%

0/4
easymcq

1. What does a React component function actually return?


Interview Questions

2 questions

Cheatsheet

Download-ready reference
Cheatsheet
Component = a function that returns a DESCRIPTION of UI (a plain element tree),
  NOT the actual DOM. React converts the description to real DOM separately.

Capitalization is NOT just style — it's a compiler rule:
  <lowercase />  → createElement("lowercase", ...)   (a string DOM tag)
  <Capitalized /> → createElement(Capitalized, ...)   (a reference to YOUR function)

Composition = components nesting other components,
  exactly like functions calling other functions.

NEVER define a component inside another component's function body —
  it becomes a NEW reference every render → React unmounts + remounts it,
  losing all state/focus, even though "logically" it's the same component.

Calling Component() directly ≠ rendering <Component />
  Direct calls skip React's tracking entirely — hooks won't work correctly.

Related topics

JavaScript FundamentalsJSXProps

On this page

20m
Knowledge CheckInterview QuestionsCheatsheet

Concept#

The beginner framing: a component is a reusable, self-contained piece of UI — you write it once (a Button, a Card, a SearchBar) and use it as many times as you need, each usage independent of the others.

The precise mental model: a React component is a plain JavaScript function that returns a description of what should appear on screen — not the actual DOM, not pixels, just a lightweight tree of plain objects (React elements) describing "there should be a <button> here, with this text." React itself is the layer that takes that description and turns it into real DOM nodes, then keeps the DOM in sync as the description changes. This distinction — component returns a description, React does the rendering — is the foundation everything else in React builds on.

function Greeting() {
  return <h1>Hello, world!</h1>;
}

Greeting is nothing more than a function. Calling it doesn't touch the DOM at all — it returns an element description (technically the same shape as { type: "h1", props: { children: "Hello, world!" } } — see JSX for exactly how that translation happens). React is what decides when to call this function and what to do with the object it returns.

Composition: building bigger components out of smaller ones#

function Icon() {
  return <span>⭐</span>;
}
 
function Button({ label }) {
  return (
    <button>
      <Icon /> {label}
    </button>
  );
}
 
function Toolbar() {
  return





Toolbar doesn't know or care how Button renders internally — it just uses it, the same way a function calls other functions. This is composition: complex UI is built by nesting simple, independent pieces, not by writing one giant function that describes everything at once.

Why component names must be capitalized#

function greeting() { return <h1>Hi</h1>; }  // lowercase — treated as an HTML TAG, not your function
function Greeting() { return <h1>Hi</h1>; }  // capitalized — treated as YOUR component
 
<greeting />   // React looks for an HTML element literally named "greeting" — renders nothing useful
<Greeting />   // React calls your function

This isn't a style convention you can safely ignore — it's a hard rule the JSX compiler uses to decide, at compile time, whether <X /> becomes createElement("x", ...) (a plain DOM tag, as a string) or createElement(X, ...) (a reference to your function). Lowercase-first is always read as a string tag name; capitalized is always read as a variable reference.


Try It#

Predict what renders before checking the solution.

function label() {
  return <span>Status</span>;
}
 
function StatusBadge() {
  return (
    <div>
      <label />
      Active
    </div>
  );
}
Solution

This renders a literal, empty HTML <label> element (the native form-label tag), followed by the text "Active" — not the label function's <span>Status</span>. Because label starts with a lowercase letter, JSX compiles <label /> to createElement("label", ...), an ordinary HTML tag reference, completely ignoring that a function named label happens to exist in scope. Renaming the function to Label (capitalized) fixes it — <Label /> would then correctly call the function.


Implement It Yourself#

Build a tiny renderer that shows exactly what "a component is a function that returns a description" means — no JSX, no React, just plain objects and function calls:

// A minimal "element" is just a plain object describing what to render.
function createElement(type, props, ...children) {
  return { type, props: { ...props, children } };
}
 
// A "component" is a function that returns one of these descriptions.
function Greeting(props) {
  return createElement("h1", null, `Hello, ${props.name}!`);


















This is a deliberately simplified version of what React's reconciler does on every render: walk the element tree, and every time it finds a function-type element, call it and recurse into whatever it returns.


Under the Hood#

There's no special "component" type in JavaScript — a React component is exactly the plain function-value concept from Fundamentals: it can be assigned to a variable, passed as an argument, returned from another function, all because functions are first-class values in JS. Composition (Toolbar using Button using Icon) is nothing more than ordinary function composition — the same idea as calling formatDate(parseDate(input)), just expressed as nested JSX instead of nested parentheses.


Common Mistakes#

1. Defining a component inside another component's body#

function Parent() {
  function Child() {          // ❌ a BRAND NEW function, created fresh on every Parent render
    return <input />;
  }
  return <Child />;
}

Because Child is redefined every time Parent renders, React sees a different function reference each time — and React identifies component types by reference, not by name or shape. A different reference means React treats it as an entirely different component, unmounting the old one and mounting a new one on every single render of Parent — destroying any state or focus Child had. Always define components at the module's top level, outside other components.

2. Forgetting a component must return a single root (or a Fragment)#

function Row() {
  return (
    <td>A</td>
    <td>B</td>   // ❌ SyntaxError — two sibling elements with no common parent
  );
}

Fix with a wrapping element or a Fragment (<>...</>), which groups children without adding an extra real DOM node.

3. Confusing a component definition with a component usage#

function Card() { return <div>Card</div>; }
 
Card();      // calls the function directly — returns an element description, doesn't render into anything
<Card />;    // tells REACT to render it — this is the form that actually participates in React's tree

Calling a component as a plain function (Card()) skips React's rendering machinery entirely — no hooks work correctly this way, since hooks rely on React tracking which component is currently rendering. Always render components via JSX (<Card />), never by invoking them directly.


Best Practices#

  • One component, one responsibility. If a component's JSX is hard to read at a glance, it's usually doing too much — extract a piece into its own named component.
  • Define components at module scope, never nested inside another component's function body.
  • Name components descriptively and in PascalCase — this isn't just style, it's what makes JSX correctly treat <YourThing /> as a component reference rather than an HTML tag.
  • Prefer composition over configuration — instead of one Button with twelve boolean props for every variant, consider several small, purpose-built components (or a children-based API) that compose together.

Performance Tips#

  • Defining a component inside another component's render body (Common Mistake #1) isn't just a state-loss bug — it's also a real performance problem, since it forces a full unmount/remount of that subtree (destroying and recreating real DOM nodes) on every parent render, instead of the cheap update React could otherwise do in place.
  • Keeping components small has a performance benefit beyond readability: smaller components make it easier to apply React.memo precisely (see Rendering Lifecycle) to exactly the subtree that's expensive to re-render, rather than being forced to memoize a large, monolithic component all-or-nothing.

(
<div>
<Button label="Save" />
<Button label="Cancel" />
</div>
);
}
}
// A tiny renderer: if `type` is a function, CALL it (that's what "calling a
// component" means). If it's a string, it's a real DOM tag — build it for real.
function render(element, container) {
if (typeof element.type === "function") {
const rendered = element.type(element.props);
return render(rendered, container);
}
const node = document.createElement(element.type);
element.props.children.forEach((child) => {
node.appendChild(typeof child === "string" ? document.createTextNode(child) : render(child));
});
container.appendChild(node);
}
render(createElement(Greeting, { name: "Ada" }), document.body);
// Produces a real <h1>Hello, Ada!</h1> — Greeting was never anything more
// than a function that got CALLED and returned a description.