Need for JSX in React — Explained with Examples

Need for JSX in React — Explained with Examples

The origin of JSX in React

One of the key differences between a good and a brilliant programmer is that the latter always understands how something is working underneath. The latter identifies an abstraction when encounters one.

Working with React, you must have come across .js files with HTML element. JSX elements are nothing but these HTML elements. JSX stands for JavaScript XML. For React with TypeScript, its .tsx, hence TypeScript XML.

As a convention, JSX elements always return a single DOM element.

For example, here the element is being assigned to a single HTML DOM element.

const element = (
  <h1>
    Hello, {formatName(user)}!
  </h1>
);

Some other examples just to be clear on what valid JSX looks like:

const element = <h1>Hello, world!</h1>;
const element = <a href="https://www.reactjs.org"> link </a>;
const element = (
  <div>
    <h1>Hello!</h1>
    <h2>Good to see you here.</h2>
  </div>
);

If you look closely, on exporting element, it will always export a single DOM parent element. You cannot return JSX like:

const element = (
  <div>
    <h1>Hello!</h1>
    <h2>Good to see you here.</h2>
  </div>
  <div>
    <h1>Sibling element</h1>
    <h2>I will break JSX element</h2>
  </div>
);

This is where the JSX will become invalid and throw an error. In the code snippet above, the element is trying to return 2 div blocks. Even though it is valid HTML, it will throw an error in JSX.

React without JSX

Yes, JSX is nothing but syntactic sugar.

“Syntactic sugar” is a term for syntax changes in computer programming, which makes it easier for humans to code.

With the advancement in React, the maintainers of React identified that it was becoming too cumbersome and verbose to write React code, which had HTML.

Consider a valid JSX:

const element = (
  <div className="container">
    <h1>Hello!</h1>
    <h2>Good to see you here.</h2>
  </div>
);

To get similar results without using JSX, we have to write a lot of verbose code using React.createElement method. This also shows we do not require JSX to produce React applications.

createElement()

React.createElement takes 3 arguments.

  1. Element: This is the HTML DOM element that we want to render. If it’s a built-in HTML element, like div, then we just need to pass a string 'div' in it.
    React.createElement('div');
    
  2. Configuration Object: This argument is an object that configures this element. Specifically, an object that sets all the attributes of the element. If the element has no attributes, we can pass an empty object. In our example, the parent div tag has a className attribute.
    React.createElement('div', {className: 'container'});
    
  3. Content: The content between the opening and closing element tag. Here, the content between the opening and closing div tag. Now, this doesn't mean we can have only 3 arguments. We can have an infinite number of arguments after the 2nd one, which will show the different contents between the opening and closing element tags.
    React.createElement('div', {className: 'container'}, , , , , , ,);
    

For example, in our example we have 2 children - <h1> and <h2> tags. Therefore, we'll have 2 more arguments passed to .createElement after the configuration object. Both these arguments will again be React.createElement.

The final code snippet, without JSX will look like:

const element = React.createElement(
    "div",
    { className: "container" },
    React.createElement("h1", {}, "Hello"),
    React.createElement("h2", {}, "Good to see you here.")
  );

The code snippet above, using React.createElement will look something like the above code. Now, if you compare the readability of the code, the JSX element makes much more sense.

const element = (
  <div className="container">
    <h1>Hello!</h1>
    <h2>Good to see you here.</h2>
  </div>
);

Hence, the JSX element is an abstraction of the API React.createElement. Because the API doesn't allow to have 2 parent elements, JSX always returns a single DOM element.

To sum it up:

This is not a valid JSX:

return (
    <h1>Hi There</h1>
    <h2>This will not work</h2>
  );

Apart from .createElement not taking multiple root HTML/DOM elements, even the code snippet below is invalid.

return (
    React.createElement('h1', {}, 'Hi There'),
    React.createElement('h2', {}, 'This will not work'),
  );

Therefore, you can’t return over one “root” JSX element. You also cannot store over 1 root JSX element in a variable.

Did you find this article valuable?

Support Aditya Tyagi by becoming a sponsor. Any amount is appreciated!