JSX without importing React

React 17 provides support for a new version of the JSX transform.
Simply put, it allows using JSX without having React in scope.

Let’s figure out why it’s possible and how it works.

The previous state of things ⏮️

Prior to React v17.0.0, JS…


This content originally appeared on DEV Community and was authored by Nick | React tinkerer ⚛️

React 17 provides support for a new version of the JSX transform.
Simply put, it allows using JSX without having React in scope.

Let's figure out why it's possible and how it works.

The previous state of things ⏮️

Prior to React v17.0.0, JSX transform used React.createElement internally.
There was one minor and one major problem with this approach:
👉 React must be in scope
👉 "Some performance improvements and simplifications" weren't possible

// Before transpilation
import React from 'react';

const Item = () => {
  return <div>Hello world!</div>;
}

// After transpilation
// React is available in global scope

const Item = () => {
  return React.createElement('div', null, 'Hello world!');
}

A whole new world ✨

Starting from React 17, JSX transform use special jsx function internally.
You don't need to import it. Instead, the transpiler automatically imports it from React package at build time.

// Before transpilation
const Item = () => {
  return <div>Hello world!</div>;
}

// After transpilation
import {jsx as _jsx} from 'react/jsx-runtime'; 

const Item = () => {
  return _jsx('div', {children: 'Hello world!'});
}

createElement 🆚 jsx

createElement vs jsx

These two functions serve the same purpose, but they are different in a few ways.
Let's take a thorough look at them and examine how it all works under the hood.

API difference

createElement takes three arguments:
👉 element type (tag name, function/class, React.Fragment)
👉 props, passed to the element
👉 children of the element

Only the first argument is mandatory.

/**
* @param type - type of the element
* @param config - props passed to the element
* @param children - children of the element
*/
function createElement(type, config, children) {
  // ...
}

jsx takes three arguments too, but they aren't the same.

👉 element type is exactly the same
👉 props, including children and excluding key
👉 key, that you use to create lists of elements

Here only the first argument is mandatory too.

/**
* @param type - type of the element
* @param config - props passed to the element, including children and excluding key
* @param maybeKey - key, that you use to create lists of elements
*/
function jsx(type, config, maybeKey) {
  // ...
}

Use cases

createElement has two use cases:
👉 manually create elements in your code
👉 transform JSX before React 17

jsx function should only be used by the compiler.
❌ You must not use it on your own.

Dev mode

createElement internally makes a couple of checks to provide meaningful warnings in development mode.

jsx function instead has two separate versions:
👉 jsx for production mode
👉 jsxDEV for development mode

That's why jsx is cleaner and shorter than createElement

// react/jsx-dev-runtime.js
export {jsxDEV} from './src/jsx/ReactJSX';

// =======================================

// react/jsx-runtime.js
export {jsx} from './src/jsx/ReactJSX';

Fundamental similarities

Despite all differences, you need to keep in mind that both functions eventually use ReactElement().
So, the output is almost identical.

export function createElement(type, config, children) {
  // ...

  return ReactElement(
    type,
    key,
    ref,
    self,
    source,
    ReactCurrentOwner.current,
    props,
  );
}

// ====================================================

export function jsx(type, config, maybeKey) {
  // ...

  return ReactElement(
    type,
    key,
    ref,
    undefined, // <- minor difference here
    undefined, // <- and here too
    ReactCurrentOwner.current,
    props,
  );
}

If you want code-to-code comparison, let me know 👇

P.S. Follow me on Twitter more content like this!


This content originally appeared on DEV Community and was authored by Nick | React tinkerer ⚛️


Print Share Comment Cite Upload Translate Updates
APA

Nick | React tinkerer ⚛️ | Sciencx (2022-02-03T19:48:50+00:00) JSX without importing React. Retrieved from https://www.scien.cx/2022/02/03/jsx-without-importing-react/

MLA
" » JSX without importing React." Nick | React tinkerer ⚛️ | Sciencx - Thursday February 3, 2022, https://www.scien.cx/2022/02/03/jsx-without-importing-react/
HARVARD
Nick | React tinkerer ⚛️ | Sciencx Thursday February 3, 2022 » JSX without importing React., viewed ,<https://www.scien.cx/2022/02/03/jsx-without-importing-react/>
VANCOUVER
Nick | React tinkerer ⚛️ | Sciencx - » JSX without importing React. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2022/02/03/jsx-without-importing-react/
CHICAGO
" » JSX without importing React." Nick | React tinkerer ⚛️ | Sciencx - Accessed . https://www.scien.cx/2022/02/03/jsx-without-importing-react/
IEEE
" » JSX without importing React." Nick | React tinkerer ⚛️ | Sciencx [Online]. Available: https://www.scien.cx/2022/02/03/jsx-without-importing-react/. [Accessed: ]
rf:citation
» JSX without importing React | Nick | React tinkerer ⚛️ | Sciencx | https://www.scien.cx/2022/02/03/jsx-without-importing-react/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.