小编典典

什么时候使用JSX.Element vs ReactNode vs ReactElement?

reactjs

我目前正在将React应用程序迁移到TypeScript。到目前为止,这很好,但是我render分别对函数的返回类型和函数组件有问题。

到目前为止,我一直用作JSX.Element返回类型,现在如果组件决定
呈现任何内容(即return)nullnull则此方法将不再起作用,因为没有有效的值JSX.Element。这是我旅程的开始,因为现在我在网上搜索并发现您应该使用ReactNode它,它还包括null可能发生的其他一些事情。这似乎是更好的选择。

但是,现在在创建功能组件时,TypeScript会抱怨ReactNode类型。再次,经过一些搜索,我发现对于功能组件,应该ReactElement改为使用。但是,如果我这样做了,兼容性问题就消失了,但是现在TypeScript再次抱怨null不是有效值。

因此,总而言之,我有三个问题:

  1. 之间有什么区别JSX.ElementReactNodeReactElement
  2. 为什么render类组件的方法返回ReactNode,而函数组件返回ReactElement
  3. 我该如何解决null呢?

阅读 1635

收藏
2020-07-22

共1个答案

小编典典

JSX.Element,ReactNode和ReactElement有什么区别?

ReactElement是具有类型和属性的对象。

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

ReactNode是ReactElement,ReactFragment,字符串,ReactNodes的数字或数组,或者为null,未定义或布尔值:

type ReactText = string | number;
type ReactChild = ReactElement | ReactText;

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

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

JSX.Element是一个ReactElement,道具的泛型类型是任意类型。它存在,因为各种库都可以以自己的方式实现JSX,因此JSX是一个全局命名空间,然后由该库设置,React对其进行如下设置:

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

例如:

 <p> // <- ReactElement = JSX.Element
   <Custom> // <- ReactElement = JSX.Element
     {true && "test"} // <- ReactNode
  </Custom>
 </p>

为什么类组件的render方法返回ReactNode,而函数组件返回ReactElement?

确实,他们确实返回了不同的东西。Component返回:

 render(): ReactNode;

函数是“无状态组件”:

 interface StatelessComponent<P = {}> {
    (props: P & { children?: ReactNode }, context?: any): ReactElement | null;
    // ... doesn't matter
}

这实际上是由于历史原因。

如何解决null问题?

键入它ReactElement | null一样不作出反应。或者让Typescript推断类型。

类型的来源

2020-07-22