【React】JSX.Element VS ReactNode VS ReactElement

3,319 阅读1分钟

引起对这个问题好奇的原因是因为,发现在日常开发中,即用了JSX.Element,又用了ReactNode,对此颇有些困惑

stackoverflow也有一样的困惑

ReactNode

可以说是最大的层级

未命名文件.jpg

我们可以顺着类型声明往上找可以发现

type ReactNode = ReactChild | ReactFragment | ReactPortal | boolean | null | undefined;

ReactNode是联合类型,由 ReactChild、ReactFragment、ReactPortal、boolean、null、undefined的集合.

  • props.children是ReactNode类型

image.png

  • class组件render返回的是ReactNode类型

image.png

render

ReactChild

type ReactChild = ReactElement | ReactText;

type ReactText = string | number;
type Key = string | number;

interface ReactElement<P = any, T extends string | JSXElementConstructor<any> = string | JSXElementConstructor<any>> {
        type: T;
        props: P;
        key: Key | null;
  }

ReactFragment

interface ReactNodeArray extends Array<ReactNode> {}
type ReactFragment = {} | ReactNodeArray;

ReactPortal

interface ReactPortal extends ReactElement {
        key: Key | null;
        children: ReactNode;
 }

JSX.Element

与ReactElement类似

declare global {
    namespace JSX {
        interface Element extends React.ReactElement<any, any> { }
        }
    }

由以上可以看出, JSX.Element是继承React.Element. 并且函数式组件一般返回JSX.Element

image.png

图中函数组件infer类型为JSX.Element

其它-Node与Element的区别

Node 是一个接口,各种类型的 DOM API 对象会从这个接口继承

Node的类型

image.png

image.png

nodeType

思考

如何判断一个元素是不是Fragment

import {isValidElement} from react;

export function isFragment(child: any): boolean {
// child.type的值是Symbol(react.fragment)
  return child && isValidElement(child) && child.type === React.Fragment;
}