DEV Community

Cover image for How JSX works?
Mohammad Bagher Abiyat
Mohammad Bagher Abiyat

Posted on • Updated on

How JSX works?

I put a post on my Twitter account and had a brief talk on how JSX works, So I want to explain more about it here.

Every ReactJS developer knows about the jsx magic, it let us write some HTML in javascript, and that's how the magic happens. We can do this kind of stuff in tools like babel.

For example, we have a babel plugin named @babel/plugin-transform-react-jsx that gives us the ability to work with JSX syntax.

Prerequisites

We just need @babel/plugin-transform-react-jsx to start, you can install it with npm or yarn:

npm install --save-dev @babel/plugin-transform-react-jsx
# or
yarn add -D @babel/plugin-transform-react-jsx
Enter fullscreen mode Exit fullscreen mode

Magic

It's the time to dig into the magic and see what happens inside. In React 17, React core team replaced the classic React.createElement with the jsx and jsx functions, so you don't need to import React anymore to write jsx. Now, the @babel/plugin-transform-react-jsx uses the jsx function by default now, check out this:

const profile = (
  <div>
    <img src="avatar.png" className="profile" />
    <h3>{[user.firstName, user.lastName].join(" ")}</h3>
  </div>
);
Enter fullscreen mode Exit fullscreen mode

By default, babel is going to compile that jsx to this plain javascript:

import { jsx as _jsx } from "react/jsx-runtime";
import { jsxs as _jsxs } from "react/jsx-runtime";

const profile = _jsxs("div", {
  children: [
    _jsx("img", {
      src: "avatar.png",
      className: "profile",
    }),
    _jsx("h3", {
      children: [user.firstName, user.lastName].join(" "),
    }),
  ],
});
Enter fullscreen mode Exit fullscreen mode

That's how the magic works, easy as that!

Let's be a magician

We all love to do magical things, why we don't do it now, so let's do it! We need that babel plugin to do some magic.

Now we can tell the plugin to use our own function instead of react's functions. For that, we need to write a small comment to tell it.

/** @jsx logJsx */
Enter fullscreen mode Exit fullscreen mode

Here we tell it, we want to use logJsx for jsx syntax. For the logJsx function, we turn the jsx into a logged statement like "It's a div, Hello Mohammad". Now let's define the logJsx function:

// the babel plugin is going to pass this function the type and props/attributes 
function logJsx(type, props) {
  console.log(`It's a ${type}, Hello ${props.name}`);
}
Enter fullscreen mode Exit fullscreen mode

We did it, check this:

<title name="Mohammad"></title> // type: "title" props: { name: "Mohammad" }
// console: It's a title, Hello Mohammad
Enter fullscreen mode Exit fullscreen mode

That's how jsx works, but in React, instead of logging, it gives us an object like this:

{
    type: "title",
    key: null,
    ref: null,
    props: {
        name: "Mohammad"
    },
    _owner: null,
    _store: {}
}
Enter fullscreen mode Exit fullscreen mode

Now we saw what's going on underneath in React. If you know any other magic, comment it or mention me on Twitter and tell me about it.

I hope you enjoyed this article and learned something new. Don't forget to share and send reactions to my article. If you wanted to tell me something, tell me on Twitter or mention me anywhere else, You can even subscribe to my newsletter and follow me on Github. 👋🏻

Latest comments (4)

Collapse
 
adnanaslam profile image
Adnan Aslam

good explanation

Collapse
 
aslemammad profile image
Mohammad Bagher Abiyat

Thanks, Adnan.

Collapse
 
ironcladdev profile image
Conner Ow

This is like the post I've been looking for. I was always wondering why babel's syntax is so different than JS. I did not know that it would compile JS for you.

Thank you so much.

Collapse
 
aslemammad profile image
Mohammad Bagher Abiyat

I'm really happy that you learned something new!