您當前的位置:首頁 > 攝影

React 元件型別定義的區別:JSX.Element vs ReactNode vs ReactElement

作者:由 Asuka109 發表于 攝影時間:2021-02-26

本文翻譯整理自 StackOverflow 問答 When to use JSX。Element vs ReactNode vs ReactElement?

元件型別定義

很多人可能在使用 TypeScript 編寫 React 應用的時候會對三種不同的函式返回值型別產生困惑,不明白它們之間的區別以及應該什麼時候使用哪一種型別才比較嚴謹。

ReactElement

是含有 props 和 type 屬性的物件:

type

Key

=

string

|

number

interface

ReactElement

<

P

=

any

T

extends

string

|

JSXElementConstructor

<

any

>

=

string

|

JSXElementConstructor

<

any

>>

{

type

T

props

P

key

Key

|

null

}

ReactNode

則是多種型別的集合:

type

ReactText

=

string

|

number

type

ReactChild

=

ReactElement

|

ReactText

interface

ReactNodeArray

extends

Array

<

ReactNode

>

{}

type

ReactFragment

=

{}

|

ReactNodeArray

type

ReactNode

=

ReactChild

|

ReactFragment

|

ReactPortal

|

boolean

|

null

|

undefined

類元件的 render 成員函式會返回 ReactNode 型別的值,而且 PropsWithChildren 型別中指定的 children 型別也是 ReactNode。

const

Comp

FunctionComponent

=

props

=>

<

div

>

{

props

children

}

<

/div>

// children?: React。ReactNode

type

PropsWithChildren

<

P

>

=

P

&

{

children?

ReactNode

}

雖然 React 的型別定義看起來寫得很複雜,但它實際上等價於:

type

ReactNode

=

{}

|

null

|

undefined

由於

{}

是所有物件的原型,你可以把幾乎任何型別賦值給 ReactNode,但絕大多數情況下應該對它進行更詳細的型別宣告。

JSX。Element

透過執行 React。createElement 或是轉譯 JSX 獲得。

const

jsx

=

<

div

>

hello

<

/div>

const

ele

=

React

createElement

“div”

null

“hello”

);

<

p

>

// <- ReactElement = JSX。Element

<

Custom

>

// <- ReactElement = JSX。Element

{

true

&&

“test”

}

// <- ReactNode

<

/Custom>

<

/p>

JSX 是一個全域性的名稱空間,不同的庫對 JSX 都可以有自己不同的實現,而 React 的實現方式就是讓

JSX.Element 等價於 ReactElement

,同時將它的泛型 props 和 type 都設為 any:

declare

global

{

namespace

JSX

{

interface

Element

extends

React

ReactElement

<

any

any

>

{

}

}

}

返回型別的不同

有的同學可能會注意到:類元件渲染方法的返回值型別和函式元件的是不一樣的,這是因為目前版本的 TypeScript 型別定義並不能準確地限定 React 實際值的範圍:

類元件型別定義

:透過 render() 返回 ReactNode,比 React 的實際值範圍更寬鬆

函式元件型別定義

:返回 JSX。Element,也比 React 的實際值範圍更寬鬆

實際上 React 類元件中的 render() 和函式元件的返回型別是一樣的,而 TypeScript 只是出於歷史原因和向後相容需要,為不同種類的元件聲明瞭不同的返回值型別。

根據 文件的規定 我們可以為元件返回值給出準確的型別定義:

type

ComponentReturnType

=

ReactElement

|

Array

<

ComponentReturnType

>

|

string

|

number

|

boolean

|

null

// 注意: 不能傳入 undefined

標簽: React  ReactNode  元件  JSX  ReactElement