JSX Produces Elements
The component in App.jsx returns syntax that resembles HTML.
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.
JSX source
-> transformed JavaScript
-> React element value
-> React render work
-> DOM commit when neededJSX 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.
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.
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.
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.
import { useState } from "react";JSX is transformed before browser execution. React elements are the JavaScript values produced by that transformed code.
A React Element Is a Description
Assign JSX to a variable without rendering it.
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.
type "h1"
props { children: "The First React Screen" }
key nullReact 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.
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.
Creating a React element does not create a DOM node. React DOM performs host creation during commit.
Element Type Determines What React Does Next
A lowercase JSX element produces a host type.
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.
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.
element type is "h1"
-> React DOM host work
element type is ChapterHeading
-> React component callCapitalization 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.
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.
const link = <a href="/learn">Start reading</a>;Values inside braces are JavaScript expressions.
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.
const heading = <h1>The First React Screen</h1>;Nested elements also become children.
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.
article element
h2 element
text
p element
textThe 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.
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.
return (
<h1>ReactBook</h1>
<p>Volume I</p>
);The transform cannot form one returned expression from those siblings. Wrap them in a meaningful parent.
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.
function App() {
return
<h1>ReactBook</h1>;
}The function returns undefined before reaching the JSX.
Open parentheses on the same line as return.
function App() {
return (
<h1>ReactBook</h1>
);
}The parentheses group one JavaScript expression and make multiline formatting safe.
Do not put a newline directly after return before a JSX expression. JavaScript automatic semicolon insertion can end the statement.
Short one-line returns do not need parentheses.
function Logo() {
return <img src="/react-mark.svg" alt="" />;
}JSX Must Be Closed
Every JSX tag needs a closing form.
<h1>ReactBook</h1>An element without children can close itself.
<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.
<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.
const heading = "<h1>ReactBook</h1>";Rendering that string as a React child displays the angle brackets as text.
This value is a React element.
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.
Do not convert JSX into HTML strings for normal rendering. Element values preserve React's component and prop model.
Elements Capture Values at Creation Time
Create an element from a variable.
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.
completed = 2;Create another element to describe the next result.
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.
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.
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.
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.
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.
function ChapterHeading() {
return <h1>The First React Screen</h1>;
}
function LessonProgress() {
return <p>0 of 6 lessons complete</p>;
}Return one nested element tree.
export default function App() {
return (
<main>
<ChapterHeading />
<LessonProgress />
</main>
);
}Trace the values in order.
- JSX creates an
Appelement inmain.jsx. - React calls
App. - JSX inside
Appproduces amainelement with component children. - React calls each child component.
- Their JSX produces
h1andpelements. - React DOM commits the corresponding DOM nodes.
Lesson Check
The following statements should now refer to different things.
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 changesSource Notes
- React documentation, Writing Markup with JSX
- React reference,
createElement - React reference, React Element
- React blog, Introducing the New JSX Transform