本文尝试分析一下,ReactNode ReactElement 和 Component 之间的关系和区别。
ReactNode
ReactNode
是一种 typescript 的类型。在使用 antd 这样的组件库的时候,可以看到某些 prop 的类型是ReactNode
,比如PageHeader
组件的 extra 属性的类型就是ReactNode
。
使用 vscode 的代码追踪,可以进入到@types/react
这个包,查看ReactNode
的类型定义如下:
1 | type ReactNode = |
可以发现,ReactNode
是一个联合类型。比较符合我们平时写代码时的直觉。
其中的ReactChild
可以继续跟踪,它的类型定义如下:
1 | type ReactText = string | number; |
可以发现ReactChild
也是一个联合类型,其中一个类型就是ReactElement
。因此可以发现,ReactNode
包含了ReactElement
。
ReactElement
ReactElement
也是一种 typescript 类型。通常,我们在使用 typescript 书写Function Component
的时候,如果加上了返回类型,会像这样:
1 | function App(): JSX.Element { |
追踪JSX.Element
可以看到
1 | declare global { |
所以JSX.Element
就是继承自ReactElement
。查看ReactElement
的类型定义如下:
1 | interface ReactElement< |
所以本质上ReactElement
就是一个对象,包含三个属性type
,props
,key
。
其中最特别的就是type
这个属性,它是一个范型,可以是string
或者JSXElementConstructor
。
多说一句,type 如果是string
,那么它可能就是类似于div
这样的字符串,代表 HTML 的原生标签。再来看JSXElementConstructor
,它的定义如下:
1 | type JSXElementConstructor<P> = |
这也是一个联合类型,一个是函数,返回ReactElement
。一个类,可以实例化为一个Component
,也就是一个类组件。
其实ReactElement
这个类型,就是代表了 React 中Element这个概念。官方解释如下:
React elements are the building blocks of React applications. One might confuse elements with a more widely known concept of “components”. An element describes what you want to see on the screen. React elements are immutable.Typically, elements are not used directly, but get returned from components.
1 | const element = <h1>Hello, world</h1>; |
Component
这里直接引用 React 的官方文档
React components are small, reusable pieces of code that return a React element to be rendered to the page. The simplest version of React component is a plain JavaScript function that returns a React element:
只看函数组件,简而言之,函数组件就是可以返回一个ReactElement
的函数。
JSX
我们平时书写Element
使用的是 JSX 语法,但是这种含有标签的语法(比如 <h1>Hello, world<h1>
)并不是 js 语法的一部分。因此我们熟悉的 JSX 语句会被编译为标准的 js 代码。
JSX is a syntax extension to JavaScript. It is similar to a template language, but it has full power of JavaScript. JSX gets compiled to React.createElement() calls which return plain JavaScript objects called “React elements”. To get a basic introduction to JSX see the docs here and find a more in-depth tutorial on JSX here.
使用 Babel 可以让我们看到 JSX 编译后的代码。如下:
1 | function Button() { |
编译后
1 | ; |