为什么 react 组件中, 都需要声明 `import React from 'react';`

663 阅读2分钟

在 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!');
}

如果没有引入 ReactReact.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 配置文件(如 .babelrcbabel.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';