在 React 17 之前,每个 React 组件都需要声明 import React from 'react';
,这是因为 JSX 语法在编译时会转换为 React.createElement
调用。如果没有引入 React
,编译器会报错,因为 React.createElement
未定义。
1. JSX 和 React.createElement
的关系
JSX 是 React 提供的一种语法糖,它允许我们以类似 HTML 的方式编写组件。例如:
function MyComponent() {
return <div>Hello, World!</div>;
}
在编译时,Babel 会将 JSX 转换为 React.createElement
调用:
function MyComponent() {
return React.createElement('div', null, 'Hello, World!');
}
如果没有引入 React
,React.createElement
就会未定义,导致运行时错误。
2. React 17 引入了新的 JSX 转换
从 React 17 开始,React 与 Babel 合作引入了一种新的 JSX 转换方式,称为 "Automatic Runtime"。这种方式不再需要显式引入 React
,因为 Babel 会自动从 react/jsx-runtime
中导入必要的函数。
使用新的 JSX 转换
在 React 17 及以上版本中,可以省略 import React from 'react';
,代码会变成这样:
function MyComponent() {
return <div>Hello, World!</div>;
}
Babel 会自动将其转换为:
import { jsx as _jsx } from 'react/jsx-runtime';
function MyComponent() {
return _jsx('div', { children: 'Hello, World!' });
}
3. 如何启用新的 JSX 转换
如果你使用的是 React 17 或更高版本,可以通过以下方式启用新的 JSX 转换:
(1)Babel 配置
在 Babel 配置文件(如 .babelrc
或 babel.config.js
)中,设置 runtime: 'automatic'
:
{
"presets": [
["@babel/preset-react", {
"runtime": "automatic"
}]
]
}
(2)Create React App
如果你使用的是 Create React App 4.0 或更高版本,默认已经启用了新的 JSX 转换,无需额外配置。
(3)手动配置
如果你手动配置了 Babel,确保安装了 @babel/plugin-transform-react-jsx
并启用 runtime: 'automatic'
:
npm install @babel/plugin-transform-react-jsx
然后在 Babel 配置中添加:
{
"plugins": [
["@babel/plugin-transform-react-jsx", {
"runtime": "automatic"
}]
]
}
4. 为什么 React 17 之前需要手动引入 React
?
在 React 17 之前,Babel 的 JSX 转换逻辑是硬编码为 React.createElement
的。因此,必须显式引入 React
,否则编译器无法找到 React.createElement
。
5. 总结
- React 17 之前:必须手动引入
React
,因为 JSX 会转换为React.createElement
。 - React 17 及之后:可以使用新的 JSX 转换(Automatic Runtime),无需手动引入
React
。 - 如何启用:通过 Babel 配置
runtime: 'automatic'
或使用 Create React App 4.0 及以上版本。
如果你正在使用 React 17 或更高版本,并且配置正确,可以放心地省略 import React from 'react';
!