React17中的JSX Transform

804 阅读1分钟

在React17以前,编译器为了把JSX语法转译成浏览器可以理解的语法,是把JSX转换成

React.createElement(type, props, children)

例如如下代码:

import React from 'react';

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

经过JSX转译后,输出结果如下:

import React from 'react';

function App() {
  return React.createElement('h1', null, 'Hello world');
}

这样的问题就是,但凡有JSX的地方,都需要引入React。而且React.createElement自身也在性能提升上有瓶颈。

React17中引入新的JSX转译函数,对于如下的代码:

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

经过新的JSX转译函数处理后,输出如下

// Inserted by a compiler (don't import it yourself!)
import {jsx as _jsx} from 'react/jsx-runtime';

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

在使用新的JSX transform时,就不用在使用JSX的地方显式引入React了。

新的JSX transform的变化点

1. 属性key从props对象中剥离

在如下的代码中

let randomObj = {key: 'foo'};
let element = <div {...randomObj} />;
element.key; // 'foo'

这种方式的缺点是,无法直接知道props对象中是否传入了一个key属性,而是得动态检查props中是否存在key属性。

React17中的jsx()函数,把key属性从props对象中剥离出来。现在该怎么写呢?

let {key, ...props} = obj;
<div key={key} {...props} />

在jsx()函数中,key从props对象中剥离出来是这样体现的:

jsx('div', props, key)