Kristofer Selbekk Bekker. Bulldog owner. Dad. React enthusiast. 🎩πŸ₯‚πŸ”

Diving into the new JSX transform

2 min read 756

Diving into the new jsx transformation

With React 17, you no longer need to import React in your files to use React. Confused? This article will tell you what you need to know in order to migrate both your code and knowledge to this new way of doing things.

What’s a JSX transform?

If you’ve ever written React, you’ve probably noticed the weird HTML-looking syntax in regular JavaScript files. That syntax is called JSX, and is not valid JavaScript. It looks like this:

const Welcome = () => {
  return <h1 className="hero">Welcome!</h1>;
};

In order to run this in a browser, you need to run your code through a compiler, typically Babel or TypeScript, which changes your code to valid JavaScript. Because, as it turns out, JSX is just another way of writing this:

const Welcome = () => {
  return React.createElement("h1", { className: "hero", children: "Welcome" });
};

So Babel or TypeScript (or whatever tool you choose) changes your code into calls to the function React.createElement – and therein lies the challenge. Because, suddenly, you have a reference to “React” in your code! If you haven’t imported React at the top of your file, JavaScript doesn’t know what to do with this compiled code either. That’s why you need to add import React from 'react' to the top of all your JSX-files.

Adding this to the top of all files is a huge stumbling block for beginners and a pain in the butt for the experts. And with React 17, you no longer need to specify it!

The React team has collaborated with the community to create a new transform, which automatically imports a new jsx-function from a new custom entry point. Your compiled code will now look like this:

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

const Welcome = () => {
  return _jsx("h1", { className: "hero", children: "Welcome" });
};

This will also have a lovely side-effect of a potentially smaller bundle size!

What do I need to do?

First, I want to reiterate that this feature is only available in React 17’s release candidate right now. It will be back-ported to older versions as well, but if you want to try it out today, you need to stick with version 17.

What you need to do depends on what you’re using to write your React app.

  • If you’re using create-react-app, you need to update to version 4.0.0 (currently in beta)
  • If you’re using Next JS, you need to update to version 9.5.3 or above
  • If you’re using Gatsby JS, you need to update to version 2.24.5 or above

If you have your own Babel config, you need to do a few more manual steps. If you’re using @babel/preset-react, update it to the newest version. If you’re using @babel/plugin-transform-react-jsx, update that one instead. And update @babel/core as well, while you’re at it.

We made a custom demo for .
No really. Click here to check it out.

npm update @babel/core @babel/preset-react

# or

npm update @babel/core @babel/plugin-transform-react-jsx

Next, update your Babel config with the following snippets:

{
  "presets": [
    [
      "@babel/preset-react",
      {
        "runtime": "automatic"
      }
    ]
  ]
}

or

{
  "plugins": [
    [
      "@babel/plugin-transform-react-jsx",
      {
        "runtime": "automatic"
      }
    ]
  ]
}

And you’re done!

Removing existing imports

Well, almost done. Because now you have tons of imports that aren’t necessary anymore! And we can’t let them hang around, can we?

Well, actually, you can. Everything will work as normal and will continue to do so for the foreseeable future. But having dead code hanging around is just a nuisance, and if you have the resources to get them removed, why not?

Instead of going through all your hundreds of components removing this by hand, the great people over at the React team have written an automatic script (a so-called codemod) that does it all for us. πŸ™Œ All you need to do is the following:

npx react-codemod update-react-imports

This will remove all imports to the default React export (import React from 'react'), and rewrite any references to hooks and other functions as named imports instead. That means React.useEffect will change to useEffect instead, and an import { useEffect } from 'react' statement will be added to the top of your file.

This latter part took me by surprise (I’ve always written them with prefix because I find it easier to both read and write), but it clears the way for creating an ES module build of React in the future. I’m sure I’ll get used to it after a while πŸ˜…

The payoff

With this annoying React import out of the way, React will be even easier to learn. There’s one less concept to remember, and things work better out of the box. And one line less to write whenever you’re bootstrapping a new JSX file.

You come here a lot! We hope you enjoy the LogRocket blog. Could you fill out a survey about what you want us to write about?

Which of these topics are you most interested in?
ReactVueAngularNew frameworks
Do you spend a lot of time reproducing errors in your apps?
YesNo
Which, if any, do you think would help you reproduce errors more effectively?
A solution to see exactly what a user did to trigger an errorProactive monitoring which automatically surfaces issuesHaving a support team triage issues more efficiently
Thanks! Interested to hear how LogRocket can improve your bug fixing processes? Leave your email:

Full visibility into production React apps

Debugging React applications can be difficult, especially when users experience issues that are difficult to reproduce. If you’re interested in monitoring and tracking Redux state, automatically surfacing JavaScript errors, and tracking slow network requests and component load time, try LogRocket.

LogRocket is like a DVR for web apps, recording literally everything that happens on your React app. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app's performance, reporting with metrics like client CPU load, client memory usage, and more.

The LogRocket Redux middleware package adds an extra layer of visibility into your user sessions. LogRocket logs all actions and state from your Redux stores.

Modernize how you debug your React apps β€” .

Kristofer Selbekk Bekker. Bulldog owner. Dad. React enthusiast. 🎩πŸ₯‚πŸ”

One Reply to “Diving into the new JSX transform”

  1. omg for reals? importing react bothered no developer ever, especially when most of us use auto-populating snippets… aside from maybe bundle size, this is the most underwhelming upgrade EVER!

Leave a Reply