介绍全新的 JSX 转换
虽然 React 17 并未包含新特性,但它将提供一个全新版本的 JSX 转换。看看怎么用吧?
先看看 React 16 的项目。react 和 react-dom 的版本都是16的。
"react": "^16.8.6",
"react-dom": "^16.8.6",
import React from 'react'; // 必须引入 React
import logo from './logo.svg';
import './App.css';
function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.jscode> and save to reload.
p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
a>
header>
div>
);
}
export default App;
必须引入 React,如果没有引入就会报错。
再看看 React 17 的项目。react 和 react-dom 的版本都是17的。
"react": "^17.0.1",
"react-dom": "^17.0.1",
// import React from 'react'; 不需要引入 React
import logo from './logo.svg';
import './App.css';
function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.jscode> and save to reload.
p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
a>
header>
div>
);
}
export default App;
你可以单独使用 JSX 而无需引入 React。
在浏览器中无法直接使用 JSX,所以大多数 React 开发者需依靠 Babel 或 TypeScript 来将 JSX 代码转换为 JavaScript。许多包含预配置的工具,例如 Create React App 或 Next.js,在其内部也引入了 JSX 转换。
React 17 提供了一个全新的,重构过的 JSX 转换的版本。升级至全新的转换完全是可选的,但升级它会为你带来一些好处:
1、使用全新的转换,你可以单独使用 JSX 而无需引入 React。
2、根据你的配置,JSX 的编译输出可能会略微改善 bundle 的大小。
3、它将减少你需要学习 React 概念的数量,以备未来之需。
新的转换有何不同?
当你使用 JSX 时,编译器会将其转换为浏览器可以理解的 React 函数调用。旧的 JSX 转换会把 JSX 转换为 React.createElement(...) 调用。
例如,假设源代码如下:
import React from 'react';
function App() {
return <h1>Hello Worldh1>;
}
旧的 JSX 转换会将上述代码变成普通的 JavaScript 代码:
import React from 'react';
function App() {
return React.createElement('h1', null, 'Hello world');
}
然而,这并不完美:
如果使用 JSX,则需在 React 的环境下,因为 JSX 将被编译成 React.createElement。有一些 React.createElement 无法做到的性能优化和简化。
为了解决这些问题,React 17 在 React 的 package 中引入了两个新入口,这些入口只会被 Babel 和 TypeScript 等编译器使用。新的 JSX 转换不会将 JSX 转换为 React.createElement,而是自动从 React 的 package 中引入新的入口函数并调用。
假设你的源代码如下:
function App() {
return <h1>Hello Worldh1>;
}
下方是新 JSX 被转换编译后的结果:
// 由编译器引入(禁止自己引入!)
import {jsx as _jsx} from 'react/jsx-runtime';
function App() {
return _jsx('h1', { children: 'Hello world' });
}
注意,此时源代码无需引入 React 即可使用 JSX 了!
注意
react/jsx-runtime 和 react/jsx-dev-runtime 中的函数只能由编译器转换使用。如果你需要在代码中手动创建元素,你可以继续使用 React.createElement。它将继续工作,不会消失。
了解更多:https://zh-hans.reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html