JSX and Rendering Mental Model
Explore the purpose and function of JSX as a syntax extension that describes user interfaces declaratively in React 19. Understand how JSX transforms into JavaScript objects representing the UI tree, how React uses this for efficient rendering, and how dynamic UI updates occur with each render. This lesson clarifies the mental model behind JSX and React's rendering process.
When building user interfaces in React, the DOM is not manipulated directly. Instead, the UI is described declaratively, and React takes responsibility for updating the DOM efficiently. JSX exists to make this description readable and expressive.
Without JSX, user interfaces would be written using deeply nested function calls, which quickly become difficult to read and maintain. JSX allows the UI to resemble HTML while still behaving like JavaScript. This is more than a syntactic improvement; it changes how UI is understood. Instead of thinking in terms of instructions, the UI is treated as a function of state.
JSX deep dive
JSX is not HTML. It is a syntax extension for JavaScript used to describe UI structure. When JSX is written, it does not create DOM elements. Instead, it produces a description of what should be rendered. For example:
function App() {return <h1>Hello, world</h1>;}
This does not create an <h1> in the DOM immediately. Instead, it creates a JavaScript object known as a React element. JSX does not perform rendering; it only describes what React should render. Because JSX compiles into JavaScript objects, it follows strict structural rules. A component must return a single root element, tags must be properly closed, and attributes must use camelCase naming. These rules ensure that JSX remains valid JavaScript.
JSX as syntax sugar
JSX is often described as syntax sugar, but this idea needs to be understood clearly. JSX is simply a more readable way of writing function calls. For example, writing:
const element = <h1>Hello</h1>;
is equivalent to:
const element = React.createElement("h1", null, "Hello");
JSX does not introduce new capabilities. It only improves readability and developer experience. Behind the scenes, both forms produce the same result: a JavaScript object describing the UI.
JSX behind the scenes
When JSX is written, it is transformed into function calls that return objects representing the UI structure. These objects form a tree that React uses internally. For example:
<div className="container"><h1>Hello</h1></div>
becomes:
React.createElement("div",{ className: "container" },React.createElement("h1", null, "Hello"));
This structure is often referred to as the Virtual DOM representation. React compares this tree with the previous version, determines what has changed, and updates only the necessary parts of the DOM. This is what makes React efficient.
How JSX becomes JavaScript
JSX is converted into JavaScript during the build process using tools like Babel or modern bundlers. Browsers never see JSX, and React does not parse JSX at runtime. This means JSX adds no performance overhead.
In React 19, this transformation may use optimized internal functions, but the mental model remains the same: JSX becomes function calls that produce element objects.
Embedding JavaScript inside JSX
JSX allows JavaScript expressions to be embedded using curly braces {}. This makes it possible to dynamically generate UI based on data. For example:
function App() {const name = "Bob";return <h1>Hello, {name}</h1>;}
Inside the curly braces, any valid JavaScript expression can be used, including variables, function calls, and calculations. However, statements such as if or for cannot be written directly inside JSX because they do not return values. JSX expects expressions that evaluate to something that can be rendered.
<p>{2 + 2}</p><p>{user.name.toUpperCase()}</p>
However, we cannot place statements like if or for directly. This is because JSX expects expressions that evaluate to values.
Dynamic rendering in JSX
Dynamic rendering is where JSX becomes powerful. Instead of defining a fixed UI, JSX allows the interface to change based on data such as state or props. This means the UI is not static. It adapts depending on the current values passed into a component. For example:
function Greeting({ isLoggedIn }) {return (<div>{isLoggedIn ? <h1>Welcome back</h1> : <h1>Please sign in</h1>}</div>);}
In this example, the rendered output depends on the value of isLoggedIn. If the value is true, one element is returned; if false, a different element is returned.
This highlights an important idea: JSX is evaluated as JavaScript during rendering. Each time a component renders, React re-executes the JSX, produces a new UI description, and compares it with the previous one. This leads to a key mental model:
JSX is re-executed on every render to produce a new UI description.