React

What is the difference between React Node, React Element, and React Component?

The short answer

A React Component is a function (or class) that returns a description of UI. A React Element is that description — a plain JavaScript object that tells React what to render. A React Node is anything React can render, which includes elements, but also strings, numbers, booleans, null, undefined, and arrays of any of those things.

These three terms describe different layers of React's rendering model, and understanding them helps you reason about what's actually happening when React builds your UI.

React Node — anything renderable

A React Node is the broadest category. It's any value that React knows how to put on the screen (or intentionally ignore). Here's the full list:

  • React Elements (JSX or React.createElement calls)
  • Strings and numbers (rendered as text nodes)
  • Booleans, null, and undefined (render nothing — this is how conditional rendering works)
  • Arrays of any of the above (React renders each item)
function Kitchen() {
return (
<div>
{/* String — valid React Node */}
{'Hello'}

{/* Number — valid React Node */}
{42}

{/* Boolean — valid React Node, renders nothing */}
{true}

{/* null — valid React Node, renders nothing */}
{null}

{/* Array of nodes — valid React Node */}
{['One', 'Two', 'Three']}

{/* Element — valid React Node */}
<p>A paragraph</p>
</div>
);
}

When you type children in a component's props, the type is React.ReactNode. That's because children can be any of these things — a string, a number, a bunch of elements, or nothing at all.

React Element — the blueprint

A React Element is a plain JavaScript object that describes what should appear on the screen. It's the return value of JSX or React.createElement. This is the part that surprises people: JSX doesn't produce DOM elements. It produces lightweight objects.

const element = <h1 className="title">Hello</h1>;

Under the hood, that JSX compiles to:

const element = React.createElement(
'h1',
{ className: 'title' },
'Hello'
);

And the result is just a plain object that looks roughly like this:

{
type: 'h1',
props: {
className: 'title',
children: 'Hello'
}
}

That object is not a DOM element. It's not on the screen. It's a description — a blueprint — that tells React "I want an h1 with this class and this text." React reads these objects and figures out what to actually create in the DOM.

Elements can also describe components, not just HTML tags:

const element = <Welcome name="Sarah" />;

// Becomes:
{
type: Welcome, // the function itself, not a string
props: { name: 'Sarah' }
}

When type is a string like 'h1', React knows it's a DOM element. When type is a function or class, React knows it needs to call that component to get more elements.

React Component — the factory

A React Component is a function (or class) that accepts props and returns React Elements. Components are reusable — they're the building blocks you compose together to create your UI.

function Greeting({ name }) {
return <p>Hello, {name}</p>;
}

Greeting is a component. When you write <Greeting name="Sarah" />, React creates a React Element with type: Greeting. Then during rendering, React calls Greeting({ name: 'Sarah' }), which returns another React Element — the <p> — which React eventually turns into a real DOM node.

The key distinction: a component is a function you write. An element is the object that function returns. You never call your components directly — React does that for you during rendering.

How they relate to each other

Think of it as a pipeline:

  1. You write Components — functions that describe UI
  2. Components return Elements — plain objects describing what to render
  3. Elements can contain Nodes — their children can be elements, strings, numbers, or arrays
function App() {
// This component (App) returns an element (<div>).
// That element's children are nodes: a string, a number, and another element.
return (
<div>
{'Welcome'}
{2026}
<Greeting name="Sarah" />
</div>
);
}

React walks this tree recursively. It sees the <div> element, renders it. It sees the string and number, creates text nodes. It sees the <Greeting> element, calls the Greeting function, gets more elements back, and keeps going until everything is resolved down to DOM elements and text.

Why the distinction matters

Understanding these layers helps you make sense of things that otherwise feel like magic:

  • Why React.Children.map exists — because children are React Nodes, and they can be arrays, strings, or elements. You need utility functions to work with them reliably.
  • Why conditional rendering works — returning false, null, or undefined from a component is fine because they're valid React Nodes that render nothing.
  • Why keys matter on elements — React uses keys on elements (not components) to track identity across renders.
  • Why you can't do <component /> — JSX with a lowercase name creates an element with a string type ('component'). Components must start with an uppercase letter so React knows the type is a function, not an HTML tag.

Why interviewers ask this

This question tests whether you understand React's mental model beyond just writing JSX. Anyone can use React, but understanding that JSX produces plain objects, that components are just functions, and that React Nodes are the broader category of renderable values — that shows you know what's happening under the surface. It's the kind of understanding that helps you debug rendering issues, build component libraries, and write correct TypeScript types for your props.