React has revolutionized UI development by introducing JSX, a syntax that blends JavaScript with HTML-like elements. While JSX simplifies the process of building components, understanding its inner workings is key to creating scalable and performant applications. This article explores how inline JavaScript within JSX is executed, the transformation process from JSX to JavaScript, and the tools used in this conversion, offering insights into the mechanics behind React's modern UI development approach.
How React JSX Gets Transformed Into JavaScript Behind the Scenes?These are the following topics that we are going to discuss:
What is JSX?
JavaScript XML or JSX is known to be an add-up in the grammar of markup languages that contain JavaScript. In many instances, JS cannot perform certain operations such as designing a website’s layout. This is why this very helpful technology is derived it enables a lot of these things to be done in JavaScript code and JavaScript code alone without the bulk of unnecessary voices.
Example:
const Greeting = () => {
return <h1>Hello, World!</h1>;
};
Under the hood, browsers don't understand JSX. Therefore, JSX must be transformed into standard JavaScript before it can be executed. This transformation process is compulsory for the seamless integration of JSX within React applications.
Why JSX?
Before directly going into the transformation process, it's essential to understand the rationale behind JSX's creation and its benefits.
- Declarative Syntax: In contrast to writing imperatively, using JSX enables the developer to create the components declaratively, just as the UI appears in an ideal world. This approach improves the code's readability hence maintenance.
- Enhanced Developer Experience: JSX enables the developer to structure the UI as a part of the component code, thus helping them to avoid the need to context switch to HTML.
- Integration with JavaScript: The primary limitation of the use of JavaScript is that the variables, functions, and conditions are integrated into the markup language where it is permitted and appropriate.
Example: Conditional Rendering in JSX
const UserGreeting = ({ isLoggedIn }) => {
return (
<div>
{isLoggedIn ? <h1>Welcome back!</h1> : <h1>Please sign up.</h1>}
</div>
);
};
- Tooling and Ecosystem Support: JSX is further enriched by an extensive array of supportive tools and libraries that make development a pleasant experience with the use of syntax highlighting, linting, and formatting.
Babel is a JavaScript compiler widely used in the React ecosystem to transform JSX into standard JavaScript. It serves as the important ladder of the JSX transformation process, enabling developers to write modern JavaScript and JSX without worrying about browser compatibility.
What is Babel?
Babel is a very famous transpiler that basically allows us to use future JavaScript in today’s browsers. In simple words, it can convert the latest version of JavaScript code into the one that the browser understands. Transpiler is a tool that is used to convert source code into another source code that is of the same level. The latest standard version that JavaScript follows is ES2020 which is not fully supported by all browsers hence we make use of a tool such as ‘babel’ so that we can convert it into the code that today’s browser understands.
- Parsing: Babel parses the JSX code to understand its structure.
- Transformation: It converts JSX syntax into equivalent JavaScript function calls (React.createElement).
- Code Generation: Babel generates the transformed JavaScript code that browsers can execute.
Babel Plugins for React:
Babel utilizes plugins to handle specific transformations. For JSX, the primary plugin is @babel/plugin-transform-react-jsx, which is responsible for converting JSX syntax into React.createElement calls.
Configuration Example:
{
"presets": ["@babel/preset-env", "@babel/preset-react"],
"plugins": ["@babel/plugin-transform-react-jsx"]
}
Understanding the step-by-step process of how JSX is transformed into JavaScript provides valuable insights into React's inner workings. Let's explore each stage in detail.
Step 1: Parsing the JSX
This is the first step in parsing, it is where Babel scans through the JSX code in a bid to understand it is structured and what it actually means.
- Lexical Analysis: Babel performs Constants collection as the first step in the code: breaking instructions into keywords, identifiers, operators, or others.
- Syntactic Analysis: It takes a grammatical approach and structure to check if the language used in the code conforms to the standards set by JavaScript and JSX.
Example: Given the following JSX code
const element = <h1 className="greeting">Hello, World!</h1>;
Babel identifies:
- const element as a variable declaration.
- <h1 className="greeting">Hello, World!</h1> as a JSX element.
Step 2: AST Generation
After parsing and understanding a particular piece of code, Babel creates an AST, which is a structure that defines the relationship between different parts of the code in tree structures.
- Nodes: Things like variables, functions, jsx tags and the like all become nodes within the AST.
- Hierarchy: The AST depicts clear inter-level associations between the aspects of code.
Visualization:
With the AST in place, Babel transforms the JSX elements into standard JavaScript function calls.
- Identify JSX Elements: Babel locates nodes representing JSX elements.
- Convert to React.createElement: Each JSX element is transformed into a React.createElement call.
const element = <h1 className="greeting">Hello, World!</h1>;
Transformed JavaScript:
const element = React.createElement(
'h1',
{ className: 'greeting' },
'Hello, World!'
);
Explanation:
- 'h1': The type of the HTML element.
- { className: 'greeting' }: The props object containing attributes.
- 'Hello, World!': The child element or text.
Step 4: Code Generation
The final stage involves generating executable JavaScript code from the transformed AST.
- Code Emission: Babel walks through the transformed AST to produce the corresponding JavaScript code.
- Optimization: Babel may perform additional optimizations, such as minification or dead code elimination, depending on the configuration.
Final Output:
const element = React.createElement(
'h1',
{ className: 'greeting' },
'Hello, World!'
);
Understanding the Transpiled Code
The transformed code, though functionally equivalent to the original JSX, operates differently under the hood. Let's do in detail to the React.createElement function to understand how it works.
React.createElement
React.createElement is a fundamental function in React that creates a React element, which is a lightweight description of what should appear on the screen.
Syntax:
React.createElement(
type,
[props],
[...children]
);
Parameters:
- type: A string representing the HTML tag (e.g., 'div', 'h1') or a React component.
- props: An object containing attributes and event handlers (e.g., { className: 'greeting' }).
- children: Child elements or text nodes.
Example:
const element = React.createElement(
'button',
{ onClick: handleClick },
'Click Me'
);
Equivalent JSX:
const element = <button onClick={handleClick}>Click Me</button>;
Advantages of React.createElement
- Flexibility: It allows dynamic creation of elements based on conditions or loops.
- Performance: React optimizes rendering by comparing elements created via React.createElement.
- Composition: Facilitates the composition of complex UIs through nested elements and components.
Optimizations and Enhancements
While Babel efficiently transforms JSX into JavaScript, several optimizations enhance performance and maintainability.
JSX Pragma and Automatic Runtime
In earlier versions of React, developers needed to import React to use JSX because React.createElement was called explicitly. However, with the introduction of the automatic JSX runtime in React 17, Babel can automatically handle JSX transformations without the need to import React explicitly.
Benefits:
- Cleaner Code: Reduces the boilerplate of importing React in every file.
- Improved Tree Shaking: Helps in eliminating unused code during the bundling process.
Configuration Example:
{
"presets": [
["@babel/preset-react", {
"runtime": "automatic"
}]
]
}
React.memo and Pure Components
Optimizing component re-renders is crucial for performance. Using React.memo or Pure Components ensures that components only re-render when necessary.
Example with React.memo:
const Greeting = React.memo(({ name }) => {
return <h1>Hello, {name}!</h1>;
});
Benefit:
- Performance: Prevents unnecessary re-renders, enhancing application performance.
Code Splitting and Lazy Loading
Dividing the application into smaller chunks and loading them on demand reduces initial load times.
Example:
const OtherComponent = React.lazy(() => import('./OtherComponent'));
function MyComponent() {
return (
<Suspense fallback={<div>Loading...</div>}>
<OtherComponent />
</Suspense>
);
}
Babel Plugins for Optimization
Babel offers various plugins that can optimize the transformed code, such as minification, dead code elimination, and more.
Example: Using babel-preset-minify:
{
"presets": ["@babel/preset-env", "@babel/preset-react", "minify"]
}
Common Mistakes and How to Avoid Them
Understanding common pitfalls when working with JSX can save time and prevent errors.
Every JSX tag must be properly closed. Forgetting to close tags can lead to compilation errors.
Incorrect:
const element = <img src="image.png">;
Correct:
const element = <img src="image.png" />;
Using class Instead of className
Since class is a reserved keyword in JavaScript, JSX uses className to assign CSS classes.
Incorrect:
const element = <div class="container"></div>;
Correct:
const element = <div className="container"></div>;
Embedding Expressions Without Curly Braces
JSX allows embedding JavaScript expressions within curly braces {}. Forgetting them can lead to unexpected behavior.
Incorrect:
const element = <h1>Hello, name!</h1>;
Correct:
const element = <h1>Hello, {name}!</h1>;
Returning Multiple Elements Without a Parent
A React component must return a single parent element. Wrapping multiple elements within a parent like <div> or using React fragments is necessary.
Incorrect:
const MyComponent = () => {
return (
<h1>Hello</h1>
<p>World</p>
);
};
Correct:
const MyComponent = () => {
return (
<>
<h1>Hello</h1>
<p>World</p>
</>
);
};
Must Read:
Conclusion
JSX is a very effective way of writing React components because it helps the developers to incorporate familiar HTML within JavaScript. Understanding this flow of conversion is imperative for the optimization of the applications built using React and the rectification of possible problems that may arise.
Babel is at the center of this transformation process, which begins from the parse of JSX to the creation of AST to the call of React.createElement and finally, the executable code in JavaScript. With even more increasing improvement and optimization, still JSX is used in the React platform to increase efficiency of the developers and the performance of the applications.
If one is able to comprehend the transformation of JSX, is in possession of the best practices and is certified against the common mistakes that developers make, there is off no doubt that the possibility of developing effective, manageable and fast React applications will be achieved.
Similar Reads
How does the JSON.parse() method works in JavaScript ?
The JSON.parse() method in JavaScript is used to convert a JSON string into a JavaScript object. This method is essential for working with JSON data, especially when fetching or processing data from APIs or external sources. Converts a JSON-formatted string into a JavaScript object.Maintains the str
2 min read
How to transform String into a function in JavaScript ?
In this article, we will see how to transform a String into a function in JavaScript. There are two ways to transform a String into a function in JavaScript. The first and easy one is eval() but it is not a secure method as it can run inside your application without permission hence more prone to th
3 min read
How JavaScript works and code is executed behind the scene ?
JavaScript is an interesting language in the world and its working procedure quite be different from other languages. JavaScript is synchronous(specific order of execution), single-threaded language(it means JavaScript can only execute one command at a time). Everything in JavaScript happens insides
3 min read
How to transform JSON text to a JavaScript object ?
JSON (JavaScript Object Notation) is a lightweight data-interchange format. As its name suggests, JSON is derived from the JavaScript programming language, but itâs available for use by many languages including Python, Ruby, PHP, and Java, and hence, it can be said as language-independent. For human
3 min read
How to Store an Object sent by a Function in JavaScript ?
When a function in JavaScript returns an object, there are several ways to store this returned object for later use. These objects can be stored in variables, array elements, or properties of other objects. Essentially, any data structure capable of holding values can store the returned object. Tabl
2 min read
How to Convert String to JSON in JavaScript?
In JavaScript, converting a string to JSON is important for handling data interchangeably between server and client, parsing external API responses, and storing structured data in applications. Below are the approaches to converting string to JSON in JavaScript: Table of Content Using JSON.parse()Us
2 min read
The Future of Javascript in 2024 [Top Trends and Predictions]
JavaScript, the language that powers the web, has undergone significant transformations since its inception in 1995. As the backbone of front-end development, JavaScript has continuously evolved to meet the demands of modern web development. From being a simple scripting language, it has grown into
14 min read
How to render a list without render a engine in JavaScript ?
Javascript render engines allow developers to render raw Javascript data into a website, in an opinionated way. Examples of these are React, Vue, Ember.js, and many others. However, these frameworks are not required to render Javascript data into a website. In this article, we will take a list of st
3 min read
How to share code between files in JavaScript ?
JavaScript is a powerful and popular programming language that is widely used for web development. One of the key features of JavaScript is its ability to share code between files. This can be useful for organizing large projects, reusing code, and maintaining code quality. In this article, we'll se
6 min read
How a Function Returns an Object in JavaScript ?
JavaScript Functions are versatile constructs that can return various values, including objects. Returning objects from functions is a common practice, especially when you want to encapsulate data and behavior into a single entity. In this article, we will see how a function returns an object in Jav
3 min read