微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

如何解决何时使用 JSX.Element、ReactNode、ReactElement?

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

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

 type Key = string | number

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

ReactNode 是一个 ReactElement、一个 ReactFragment、一个字符串、一个数字或一个 ReactNode 数组,或者是 null,或者 undefined,或者是一个布尔值:

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,props 的泛型类型是 any。它存在,因为各种库可以以自己的方式实现 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像 react 一样输入它。或者让 Typescript 推断类型。

类型的来源

解决方法

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

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

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

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

  1. JSX.ElementReactNode和有什么区别ReactElement
  2. 为什么render类组件的方法返回ReactNode,而函数组件返回ReactElement
  3. 我该如何解决这个问题null

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。