Volume I index
The First React Screen

JSX Produces Elements

Ishtmeet Singh @ishtms/July 14, 2026/9 min read
#react#jsx#react-elements#rendering#javascript

The component in App.jsx returns syntax that resembles HTML.

jsx
function ChapterHeading() {
  return <h1>The First React Screen</h1>;
}

The browser does not execute that JSX source directly. Vite transforms it into JavaScript that creates a React element value. React receives the value during rendering. React DOM can later create or update a browser h1 during commit.

Those steps happen in a fixed order.

text
JSX source
  -> transformed JavaScript
  -> React element value
  -> React render work
  -> DOM commit when needed

JSX source and runtime values are different. JSX is transformed into JavaScript calls, those calls create React elements, and React reads those elements while rendering.

JSX Is Source Syntax

JavaScript does not normally allow an angle-bracket element inside a return statement.

jsx
return <h1>The First React Screen</h1>;

The .jsx extension tells Vite and its React plugin that the file can contain JSX. The transform converts the syntax before the browser evaluates the module.

With the current automatic JSX runtime, transformed output conceptually resembles this call.

js
jsx("h1", { children: "The First React Screen" });

The exact helper name and development output are tool implementation details. The stable result is a React element value whose type refers to h1 and whose props include its children.

Older JSX transforms commonly produced React.createElement calls.

js
React.createElement("h1", null, "The First React Screen");

Both forms produce React elements. A current Vite project does not need import React from "react" merely so JSX can compile. You still import named React APIs when the file uses them.

jsx
import { useState } from "react";

A React Element Is a Description

Assign JSX to a variable without rendering it.

jsx
const heading = <h1>The First React Screen</h1>;

No h1 appears in the document merely because this line ran. The variable holds a React element object.

At a supported conceptual level, the element records a type, props, and an optional key.

text
type  "h1"
props { children: "The First React Screen" }
key   null

React element objects are intended to be treated as opaque values. Their development console representation contains internal fields that can change and should not become application dependencies.

The element says what should participate in a React tree. It does not contain a live DOM node, layout dimensions, computed CSS, or methods such as focus.

jsx
const heading = <h1>The First React Screen</h1>;
heading.focus();

That call fails because the React element is not the browser element. A ref can provide access to a DOM node when an imperative browser operation is required.

Element Type Determines What React Does Next

A lowercase JSX element produces a host type.

jsx
const heading = <h1>ReactBook</h1>;

Its type identifies the web host element name h1. React DOM knows how to create or update that browser element.

An uppercase JSX element uses a JavaScript value as its type.

jsx
const heading = <ChapterHeading />;

Its type points to the ChapterHeading function. When React processes the element, it calls that component and continues through the returned content.

text
element type is "h1"
  -> React DOM host work

element type is ChapterHeading
  -> React component call

Capitalization determines the element type. A lowercase JSX name becomes a host type string; an uppercase name resolves to a JavaScript component binding.

Props Become Part of the Element

JSX attributes become props on the produced element.

jsx
const progress = <progress value={2} max={6} />;

The resulting element describes the host type progress with numeric value and max props.

Quoted values are strings.

jsx
const link = <a href="/learn">Start reading</a>;

Values inside braces are JavaScript expressions.

jsx
const total = 6;
const progress = <progress value={2} max={total} />;

JSX evaluates the expressions between braces and collects their results into a new element description.

Nested JSX Becomes children

Text between opening and closing tags becomes a child.

jsx
const heading = <h1>The First React Screen</h1>;

Nested elements also become children.

jsx
const card = (
  <article>
    <h2>JSX Produces Elements</h2>
    <p>Lesson 5 of 6</p>
  </article>
);

The outer article element has two element children. Each child is created as a React element value before the outer element description is complete.

Conceptually, the data forms a tree.

text
article element
  h2 element
    text
  p element
    text

The browser DOM can later have a similar host tree, but the React element tree exists first as JavaScript values.

These nested values become the element's children. A single child can be one value; several children are represented as a collection.

One JSX Expression Can Describe a Whole Tree

A function returns one value from one return statement.

jsx
function App() {
  return (
    <main>
      <h1>ReactBook</h1>
      <p>Volume I</p>
    </main>
  );
}

The return value is the outer main element. That one value contains its nested children.

Two adjacent JSX elements are two expressions and cannot occupy the same return position without a parent grouping.

jsx
return (
  <h1>ReactBook</h1>
  <p>Volume I</p>
);

The transform cannot form one returned expression from those siblings. Wrap them in a meaningful parent.

jsx
return (
  <main>
    <h1>ReactBook</h1>
    <p>Volume I</p>
  </main>
);

Fragments group siblings without creating a DOM wrapper. Use a real HTML parent when the document needs that element for meaning, layout, or behavior.

Parentheses Protect a Multiline Return

JavaScript can insert a semicolon after a bare return followed by a newline.

jsx
function App() {
  return
    <h1>ReactBook</h1>;
}

The function returns undefined before reaching the JSX.

Open parentheses on the same line as return.

jsx
function App() {
  return (
    <h1>ReactBook</h1>
  );
}

The parentheses group one JavaScript expression and make multiline formatting safe.

Short one-line returns do not need parentheses.

jsx
function Logo() {
  return <img src="/react-mark.svg" alt="" />;
}

JSX Must Be Closed

Every JSX tag needs a closing form.

jsx
<h1>ReactBook</h1>

An element without children can close itself.

jsx
<img src="/react-mark.svg" alt="" />

HTML source permits selected omitted end tags. JSX uses a JavaScript expression grammar and requires explicit closure.

Component elements follow the same syntax.

jsx
<LessonProgress />

A missing close prevents the file from transforming. Vite reports a syntax location because no React element value can be produced from invalid JSX.

JSX Is Not an HTML String

This value is a string.

js
const heading = "<h1>ReactBook</h1>";

Rendering that string as a React child displays the angle brackets as text.

This value is a React element.

jsx
const heading = <h1>ReactBook</h1>;

Rendering the element asks React DOM for an h1 host element.

React does not parse normal strings as HTML. That behavior protects ordinary text from becoming executable markup. The separate dangerouslySetInnerHTML prop bypasses normal text handling; use it only with trusted or correctly sanitized HTML.

Elements Capture Values at Creation Time

Create an element from a variable.

jsx
let completed = 1;
const progress = <p>{completed} lesson complete</p>;

The expression reads completed while creating the element. Assigning another number later does not mutate the existing element.

jsx
completed = 2;

Create another element to describe the next result.

jsx
const nextProgress = <p>{completed} lessons complete</p>;

React components do this during each render. Current props and state produce new element descriptions. React compares the next tree with its current tree and commits the needed host changes.

Do not mutate element props after creation.

jsx
progress.props.children = "Changed";

React treats element descriptions as immutable. Development builds can freeze elements and their props shallowly to expose mutation attempts.

Element Creation Is Cheap Relative to Host Work

Creating an element produces a small JavaScript record. It does not perform layout, paint, or DOM insertion.

jsx
const first = <LessonProgress completed={1} />;
const second = <LessonProgress completed={2} />;

Neither element affects the page until it becomes part of content rendered by a root or another component.

This also means conditional code can choose among elements before React commits a result.

jsx
const status = complete
  ? <p>Chapter complete</p>
  : <p>Continue reading</p>;

Both branches are JavaScript expressions that can produce React element values.

Inspect an Element Without Depending on Internals

Use a temporary log.

jsx
const heading = <h1>ReactBook</h1>;
console.log(heading);

The browser console shows an object containing React fields. Inspecting it can confirm that JSX did not create a DOM node.

Do not read private-looking fields or copy the console object format into application code. Use JSX, createElement, cloneElement in its limited supported cases, and React APIs to create and operate on elements.

Remove the log after inspection. Strict Mode and later renders can otherwise produce more logs than the visible page changes.

Complete the Current App

Use the small components already in App.jsx.

jsx
function ChapterHeading() {
  return <h1>The First React Screen</h1>;
}

function LessonProgress() {
  return <p>0 of 6 lessons complete</p>;
}

Return one nested element tree.

jsx
export default function App() {
  return (
    <main>
      <ChapterHeading />
      <LessonProgress />
    </main>
  );
}

Trace the values in order.

  1. JSX creates an App element in main.jsx.
  2. React calls App.
  3. JSX inside App produces a main element with component children.
  4. React calls each child component.
  5. Their JSX produces h1 and p elements.
  6. React DOM commits the corresponding DOM nodes.

Lesson Check

The following statements should now refer to different things.

text
JSX is source syntax
a React element is a JavaScript description
a component returns renderable content
a DOM element is a browser node
commit is when React DOM applies host changes

Source Notes