< Articles


Why Does React Need To Be In Scope?

This is going to be a super short article today but I wanted to share something cool I learned last week. In an attempt to keep myself up to date, I read through the React 17 summary post. In it, they describe the underlying reason we see an all too common error:

'React' must be in scope when using JSX

I've always wondered, "Why does React need to be in scope when I'm not actually using the module?" Take this simple component for example:

function App() {
    return <h1>Hello World</h1>;
}

Not once in the component itself do I actually use React. Under the hood though, React transforms our JSX into this:

function App() {
    return React.createElement("h1", null, "Hello world");
}

As mentioned in their blog post, the conversion happens because the browser doesn't recognize JSX. React has to convert it from JSX to Javascript and when it does, React is now in scope. Without the import, React.createElement will throw an exception.

The solution is to add the React import to the top of our file like so:

import React from "react";

function App() {
    return <h1>Hello World</h1>;
}

With React 17 though, this won't be necessary. Our code no longer needs the import:

function App() {
    return <h1>Hello World</h1>;
}

And our compiled code ends up looking like this:

// Inserted by a compiler (don't import it yourself!)
import { jsx as _jsx } from "react/jsx-runtime";

function App() {
    return _jsx("h1", { children: "Hello world" });
}

Pretty cool. And now that we've learned why it's done that way, it's going away.

(Insert diatribe about the rapidly changing nature of software and how learning sometimes feels like snipe hunting)

(Insert additional diatribe about snipe hunting as a scout and being promised great riches by the older boys if I caught one)

In all seriousness though, learning stuff like this is great. It's difficult to innovate in the adjacent possible unless we're first at the cutting edge of a given technology.