May 31, 2021 Article blog
2. What's the difference between the new transformations?
3. How to upgrade to a new conversion
In the early hours of September 23, Beijing time, the React team released a blog about the new JSX transformation, along with a version of React 17.0.0-rc.2, which no longer relies on the React environment and automatically introduces a new runtime when converting.
Original link: reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html
By Luna Ruan
Translator: QC-L
Launched on react Chinese documentation blog, you're welcome to follow https://zh-hans.reactjs.org or follow the imprint Chinese public number.
Although React 17 does not include the new feature , it will provide a completely new version of the JSX conversion. In this article, we'll describe what it is and how to use it.
JSX is not available directly in the browser, so most React developers rely on Babel or TypeScript to convert JSX code to JavaScript. Many preconfigured tools, such as the Create React app or Next .js, also introduce JSX transformations internally.
React 17 was released immediately, and while we wanted to improve the JSX transformation, we didn't want to break the existing configuration. So we chose to partner with Babel to provide a completely new version of the reconfigured JSX transformation for developers who want to upgrade.
Upgrading to a brand new conversion is entirely optional, but upgrading will bring you some benefits:
This upgrade does not change the JSX syntax and is not required. The old JSX transformation will continue to work and there are no plans to unblock it.
The RC version of React 17 has introduced support for the new transform, so you can give it a try! T o make it easier for everyone to use, we also plan to support React 16.x, React 15.x, and React 0.14x after React 17 is officially released. You can find upgrade instructions for different environments in the
Next, let's carefully compare the differences between old and new transformations.
When you use JSX, the compiler converts it to a
react
function call that the browser can understand.
The old JSX conversion
converts the JSX to
React.createElement(...)
call.
For example, suppose the source code is as follows:
import React from 'react';
function App() {
return <h1>Hello World</h1>;
}
The old JSX conversion turns the above code into plain JavaScript code:
import React from 'react';
function App() {
return React.createElement('h1', null, 'Hello world');
}
note
There is no need to change the source code. We'll show you how JSX transformation turns your JSX source code into JavaScript code that your browser can understand.
However, this is not perfect:
React
environment because JSX will be compiled into
React.createElement
React.createElement
can't do.
To address these issues, React 17 introduced two new portals in React's package that will only be used by compilers such as Babel and TypeScript. T
he new JSX transformation
does not convert JSX to
React.createElement
but automatically introduces new entry functions and calls them from React's package.
For example:
function App() {
return <h1>Hello World</h1>;
}
The conversion will now be to:
// 由编译器引入(禁止自己引入!)
import {jsx as _jsx} from 'react/jsx-runtime';
function App() {
return _jsx('h1', { children: 'Hello world' });
}
Note that at this point the source code does not need to be introduced to React to use JSX! ( However, You Still Need To Introduce React To Use The Hook Or Other ExportS ProvideD By React.) )
This change is compatible with all existing JSX code, so you don't need to modify the component. If you're interested in this, you can check out RFC for details of the new conversion effort.
note
Functions in
react/jsx-runtime
andreact/jsx-dev-runtime
can only be used by compiler conversions. I f you need to create elements manually in your code, you can continue to useReact.createElement
It will continue to work and will not go away.
If you're not ready to upgrade to a brand new JSX transformation, or if you're using JSX for another library, don't worry that the old conversion won't be removed and will continue to be supported.
If you want to upgrade, you need to prepare two things:
Since the new JSX transformation does not depend on the React environment, we have prepared an automated script to remove unnecessary ingestions from your code.
The React Create app is already compatible with it and will be available in the upcoming v4.0 release, which is in beta.
Next.js's v9.5.3 is compatible with the React version with the new conversion.
Gatsby's v2.24.5 will use the new conversion to be compatible with the React version.
note
If you encounter error in Gatsby, upgrade to
17.0.0-rc.2
and runnpm update
to resolve the issue.
Babel's v7.9.0 (14) and above versions support the new JSX conversion.
First, you need to update to the latest version of the Babel and transform plug-ins.
If you are using
@babel/plugin-transform-react-jsx
:
# npm 用户
npm update @babel/core @babel/plugin-transform-react-jsx
# yarn 用户
yarn upgrade @babel/core @babel/plugin-transform-react-jsx
If you are using
@babel/preset-react
:
# npm 用户
npm update @babel/core @babel/preset-react
# yarn 用户
yarn upgrade @babel/core @babel/preset-react
Currently, the default option for the old conversion is
"runtime": "classic"
To enable the new conversion, you can use
{"runtime": "automatic"}
option
@babel/plugin-transform-react-jsx
or
@babel/preset-react
// 如果你使用的是 @babel/preset-react
{
"presets": [
["@babel/preset-react", {
"runtime": "automatic"
}]
]
}
// 如果你使用的是 @babel/plugin-transform-react-jsx
{
"plugins": [
["@babel/plugin-transform-react-jsx", {
"runtime": "automatic"
}]
]
}
Starting with Babel 8,
"automatic"
integrates the two plug-ins into rumtime by default.
For more information, please refer to
the @babel/plugin-transform-react-jsx
and
@babel/preset-react
in the Babel documentation.
note
If you're using a library other than React when you're using JSX, you can introduce it from that library using the
importSource
option , provided it provides the necessary entry points. Or you can continue to use the classic conversion, which will continue to be supported.
If you are using
eslint-plugin-react,
where
react/jsx-uses-react
and
react/react-in-jsx-scope
will no longer be needed, you can close them or delete them.
{
// ...
"rules": {
// ...
"react/jsx-uses-react": "off",
"react/react-in-jsx-scope": "off"
}
}
TypeScript will support the new JSX conversion in the v4.1 beta version.
Flow will support the new JSX transformation in v0.126.0 .
Because the new JSX transformation automatically introduces the necessary
react/jsx-runtime
when you use JSX, there is no need to introduce React. T
his may result in an unused React introduction in your code.
It doesn't hurt to keep them, but if you want to delete them, we recommend running
a "codemod"
script to automatically delete them:
cd your_project
npx react-codemod update-react-imports
note:
If you get an error running codemod, try using
npx react-codemod update-react-imports
select a different JavaScript environment. E specially when you choose JavaScript with Flow, you can choose it even if you're not using Flow because it supports newer syntax than JavaScript. If you're having trouble, please let us know.Note that codemod's output may not match your code style, so you may need to perform Prettier after codemod is complete to ensure that the format is the same.
Running codemod does the following:
import React from "react"
will become
import { useState } from "react"
which will be the preferred style for future development.
Codemod
does not
affect the way namespaces are introduced (i.e., import as React from
import * as React from "react"
which is also a valid style, and the default introduction will continue to work in React 17, but in the long run we recommend that you try not to use them.
example:
import React from 'react';
function App() {
return <h1>Hello World</h1>;
}
will be replaced by
function App() {
return <h1>Hello World</h1>;
}
If you use react's other exports, such as Hook, codemod converts them to named imports.
example:
import React from 'react';
function App() {
const [text, useText] = React.useState('Hello World');
return <h1>{text}</h1>;
}
will be replaced
import { useState } from 'react';
function App() {
const [text, useText] = useState('Hello World');
return <h1>{text}</h1>;
}
In addition to cleaning up unused ingestions, this tool can also help you pave the way for future major versions of React (not React 17), which will support ES modules and do not export by default.
We would like to thank Babel, TypeScript, Create React App, Next.js, Gatsby, ESLint, and Flow's key maintainers for the implementation and integration of the new JSX transformation. We would also like to thank the React community for their feedback and discussions on the relevant RFC.
The new feature is not included: /blog/2020/08/10/react-v17-rc.html
[2] Babel: https://babeljs.io/blog/2020/03/16/7.9.0#a-new-jsx-transform-11154httpsgithubcombabelbabelpull11154
[3] RC version of React 17: /blog/2020/08/10/react-v17-rc.html
Below: #how-to-upgrade-to-the-new-jsx-transform
Performance optimization and simplification: https://github.com/reactjs/rfcs/blob/createlement-rfc/text/0000-create-element-changes.md#motivation
[7] RC version of React 17: /blog/2020/08/10/react-v17-rc.html
We have prepared an automatic script: #removing-unused-react-imports
Compatibility support for it: https://github.com/facebook/create-react-app/pull/9645
Upcoming v4.0 release: https://gist.github.com/iansu/282dbe3d722bd7231fa3224c0f403fa1
[11]v9.5.3: https://github.com/vercel/next.js/releases/tag/v9.5.3
[12]v2.24.5: https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby/CHANGELOG.md#22452-2020-08-28
[13] Error: https://github.com/gatsbyjs/gatsby/issues/26979 encountered in Gatsby
[14]v7.9.0: https://babeljs.io/blog/2020/03/16/7.9.0
[15]@babel/plugin-transform-react-jsx: https://babeljs.io/docs/en/babel-plugin-transform-react-jsx
[16]@babel/preset-react: https://babeljs.io/docs/en/babel-preset-react
[17]
importSource
option:
https://babeljs.io/docs/en/babel-preset-react#importsource
[18]eslint-plugin-react: https://github.com/yannickcr/eslint-plugin-react
[19]v4.1 beta: https://devblogs.microsoft.com/typescript/announcing-typescript-4-1-beta/#jsx-factories
[20]v0.126.0: https://github.com/facebook/flow/releases/tag/v0.126.0
[21]“codemod”: medium.com/@cpojer/effective-javascript-codemods-5a6686bb46fb
Let us know: https://github.com/reactjs/react-codemod/issues
[23] Prettier: https://prettier.io/
[24] RFC: https://github.com/reactjs/rfcs/pull/107
That's
W3Cschool编程狮
has to say
about the official release of React 17.0.0-rc.2, introducing a new JSX transformation.