Imagining React Without JSX: A Developer's Worst Nightmare
React has revolutionized how we build user interfaces with JavaScript, simplifying the once-tedious process of managing UI components. But what if we lived in a world without JSX? Imagine coding React applications using only React.createElement()
instead of the clean and intuitive JSX syntax. Let’s take a journey through this nightmare and explore why JSX is a lifesaver for developers.
React Without JSX: Enter React.createElement()
To understand the value of JSX, let’s first create a simple "Hello World" example using React.createElement()
:
const heading = React.createElement("h1", {}, "Hello World From React!");
Here, React.createElement()
takes three arguments:
- The tag you want to create (
"h1"
). - An object representing attributes or properties for that tag, such as
{id: "heading"}
. - The content to place inside the tag (
"Hello World From React!"
).
This creates a React element, but there’s more to it. React needs a root to render its elements in the DOM. For that, we need ReactDOM:
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(heading);
This works, but it’s not exactly elegant. Let’s not even get started on writing everything inside a <script>
tag! Instead, we can create a separate app.js
file, which is more maintainable.
Nested HTML with React.createElement()
Now, let’s kick it up a notch and create a nested HTML structure. For example, adding an h1
inside a div
:
const parent = React.createElement(
"div",
{ id: "parent" },
React.createElement(
"div",
{ id: "child" },
React.createElement("h1", {}, "I am an H1 Tag")
)
);
Do you see the issue already? This approach gets cumbersome fast, especially for more complex components. Imagine creating multiple nested tags or siblings. Here’s how you’d handle siblings:
const parent = React.createElement(
"div",
{ id: "parent" },
React.createElement(
"div",
{ id: "child" },
[
heading,
React.createElement("h1", {}, "I am an H1 Tag")
]
)
);
Now, throw in the key
prop React requires for list items, and it quickly turns into a developer's worst nightmare. Error messages like "Each child in a list should have a unique key
prop" can make your code even harder to manage.
The JSX Revolution
So, what’s the solution? Enter JSX—a game-changer introduced by Facebook’s React team. JSX is not just a shortcut for writing HTML in JavaScript; it’s a syntax extension that allows you to write your UI components declaratively.
Goodbye React.createElement()
, Hello JSX
Let’s rewrite the same nested structure using JSX:
const jsxheading = <h1 id="heading">Namaste React using JSX</h1>;
Look at how clean and readable this is compared to the clunky React.createElement()
method. JSX allows us to focus on building components rather than wrangling with verbose syntax.
Here’s how it looks in action:
import React from "react";
import ReactDOM from "react-dom/client";
const jsxheading = <h1 id="heading">Namaste React using JSX</h1>;
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(jsxheading);
What JSX Does Under the Hood
But wait—browsers don’t understand JSX, right? That’s correct! JSX is not valid HTML or JavaScript. It’s simply syntactic sugar that, during the build process, is converted by Babel into React.createElement()
calls. For example:
const jsxheading = <h1 id="heading">Namaste React using JSX</h1>;
gets transformed into:
const jsxheading = React.createElement("h1", { id: "heading" }, "Namaste React using JSX");
The result is the same, but JSX makes the code infinitely more readable and maintainable for humans.
Babel the transpiler:
Babel transpiles JSX into browser-understandable JavaScript code. Here's a brief explanation of how it works:
JSX Syntax: JSX is a syntax extension for JavaScript that allows you to write HTML-like code within JavaScript. Browsers, however, can't directly understand JSX because it's not valid JavaScript.
Parsing: Babel parses the JSX code into an Abstract Syntax Tree (AST), which is a tree representation of the structure of the code. It breaks down JSX tags and expressions into nodes of the tree.
Transformation: Babel transforms JSX tags into JavaScript function calls. For example,
<div>Hello</div>
becomesReact.createElement('div', null, 'Hello')
. This functionReact.createElement
creates a virtual DOM element.Output: The transformed JSX is now valid JavaScript, which browsers can execute. The output JavaScript file contains these
React.createElement
calls instead of JSX, and the browser renders the appropriate DOM elements when this JavaScript runs.
This process allows you to write JSX in your React components, but Babel ensures that the browser only sees standard JavaScript it can execute.
Why JSX Is a Lifesaver
The most expensive operation on a webpage is manipulating the DOM. React’s philosophy is all about minimizing these costly DOM updates using a virtual DOM, and JSX makes this process much easier for developers to handle.
JSX simplifies code, enhances readability, and allows us to write UI components more declaratively, like combining logic and HTML in a single file. This is especially important in modern web development, where building complex UIs requires clean, maintainable code.
Conclusion: The Nightmare Without JSX
Imagine trying to build entire applications using only React.createElement()
—every tag, every attribute, every piece of content wrapped in function calls. JSX is the hero that saves us from this complexity, allowing us to write more elegant, readable, and maintainable code. While you technically can write React without JSX, would you really want to?
Goodbye React.createElement()
—Hello JSX!
Top comments (0)