何时使用JSX.Element vs ReactNode vs ReactElement?

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

我一直使用JSX.Element作为返回类型,现在,如果组件决定呈现任何内容,即返回null,则这不再有效,因为null不是JSX.Element的有效值。这是我旅程的开始。我在网上搜索了一下,发现应该改用ReactNode,其中包括null和其他一些可能发生的事情

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

长话短说,我有三个问题:

  1. JSX.ElementReactNodeReactElement之间有什么区别
  2. 为什么类组件的render方法返回ReactNode,而功能组件返回ReactElement
  3. 对于null,如何解决此问题

元素、ReactNode和ReactElement之间的区别是什么

ReactElement是具有类型和道具的对象

类型键=字符串|编号
界面元素<P=any,T扩展字符串| JSXElementConstructor<任何>=字符串| JSXElementConstructor<任何&gt&燃气轮机;{
类型:T;
道具:P;
key:key | null;
}

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

类型:文本=字符串|编号;
类型ReactChild=ReactElement | ReactText;
接口ReactNodeArray扩展阵列<反应节点>{}
类型ReactFragment={}| ReactNodeArray;
类型ReactNode=ReactChild | ReactFragment | ReactPortal | boolean | null |未定义;

Element是一个ReactElement,props的泛型类型是any。它是存在的,因为各种库可以以自己的方式实现JSX,因此JSX是一个全局名称空间,然后由库设置,反应如下:

声明全局{
名称空间JSX{
接口元素扩展了React.ReactElement<any,any>{}
}
}

举例来说:

<p>/<-ReactElement=JSX.Element
<定制>//<-ReactElement=JSX.Element
{正确的测试}/<-反应节点
&lt/定制>
&lt/p>

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

事实上,它们确实返回了不同的东西组件s返回:

render():ReactNode;

和功能是;“无状态组件”:

接口组件<P={}>{
(props:P&{children?:ReactNode},context?:any):ReactElement | null;
//…没关系
}

这实际上是历史原因造成的

关于null,我如何解决这个问题

将其输入为ReactElement | null,就像react一样。或者让Typescript推断类型

类型的来源

发表评论