react17.0.0新发现小问题

2,626 阅读3分钟

问题:原来react项目中需要引入react(react 17.0.0 之前),前不久发布react17.0.0之后可以不用引入

想法:

  • 开始以为编辑器帮我引入了

  • 脚手架在webpack内置了这个模块

  • 例子 先创建一个项目先

create-react-app demo

import React, { Component } from 'react'

export default class App extends Component {
  render() {
    return (
      <div>
        React 组件
      </div>
    )
  }
}

启动后显示:

//16.x 之前要引入react
import React, { Component } from 'react'

export default class App extends Component {
  render() {
  //   return (
  //     <div>
  //       React 组件
  //     </div>
  //   )
  return React.createElement('div',{},'React 组件-通过create创建')
  }
}
//没引入
src\App.js
  Line 10:10:  'React' is not defined  no-undef        

Search for the keywords to learn more about each error.
//17.0.0 不引入
import  { Component } from 'react'

export default class App extends Component {
  render() {
    return (
      <div>
        React 组件
      </div>
    )
  // return React.createElement('div',{},'React 组件-通过create创建')
  }
}

原因:react官方文档 提到这么一句话:通过新的转换,您可以使用JSX而不导入React。

新的转换有何不同? 当你使用 JSX 时,编译器会将其转换为浏览器可以理解的 React 函数调用。旧的 JSX 转换会把 JSX 转换为 React.createElement(...) 调用。

例如,假设源代码如下:

import React from 'react';

function App() {
  return <h1>React 组件</h1>;
}

旧的 JSX 转换会将上述代码变成普通的 JavaScript 代码:

import React from 'react';

function App() {
  return React.createElement('h1', null, 'React 组件');
}

注意 无需改变源码。我们将介绍 JSX 转换如何将你的 JSX 源码变成浏览器可以理解的 JavaScript 代码。

但是,这并不完美:

  • 因为JSX已编译到React.createElement中,所以如果您使用JSX,则React必须在范围内。

  • 有一些React.createElement不允许的性能改进和简化。

为了解决这些问题,React 17在React包中引入了两个新的入口点,仅供Babel和TypeScript等编译器使用。 新的JSX转换没有将JSX转换为React.createElement,而是自动从React包中的那些新入口点导入特殊功能并调用它们。

假设您的源代码如下所示:

function App() {
  return <h1>Hello World</h1>;
}

这是新的JSX转换将其编译为:

//由编译器插入(不要自己导入!)'react / jsx-runtime'导入{jsx as _jsx};

function App(){

return _jsx('h1',{children:'Hello world'});

}

注意我们的原始代码如何不再需要导入React来使用JSX! (但是我们仍然需要导入React才能使用Hooks或React提供的其他导出。)

此更改与所有现有的JSX代码完全兼容,因此您不必更改组件。 如果您好奇,可以查看技术RFC,以获取有关新转换如何工作的更多详细信息。

注意 react / jsx-runtime和react / jsx-dev-runtime内部的函数只能由编译器转换使用。 如果需要在代码中手动创建元素,则应继续使用React.createElement。 它将继续工作,并且不会消失。

如何升级到新的JSX转换

如果您还没有准备好升级到新的JSX转换,或者您正在将JSX用于其他库,请不用担心。 旧的转换将不会被删除,并将继续得到支持。

如果要升级,则需要两件事:

支持新转换的React版本(React 17 RC及更高版本支持它,但我们还为仍然使用较早主要版本的用户发布了React 16.14.0,React 15.7.0和React 0.14.10) 。

兼容的编译器(请参阅下面有关不同工具的说明)。

由于新的JSX转换不需要将React纳入范围,因此我们还准备了一个自动化脚本,该脚本将从您的代码库中删除不必要的导入。

参考资料: react 17版本