本文介绍了什么时候使用JSX.Element vs ReactNode vs ReactElement?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在将React应用程序迁移到TypeScript.到目前为止,这还算不错,但是我的render函数和函数组件的返回类型都存在问题.

I am currently migrating a React application to TypeScript. So far, this works pretty well, but I have a problem with the return types of my render functions respectively my function components.

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

So far, I had always used JSX.Element as return type, now this doesn't work any more if a component decides to not render anything, i.e. return null, since null is no valid value for JSX.Element. This was the beginning of my journey, because now I searched the web and found that you should use ReactNode instead, which also includes null and also a few other things that can happen. This seemed to be the better bet.

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

However, now when creating a function component, TypeScript complains about the ReactNode type. Again, after some searching I found, that for function components you should use ReactElement instead. However, if I do so, the compatibility issue is gone, but now TypeScript again complains about null not being a valid value.

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

So, to cut a long story short, I have three questions:

  1. JSX.ElementReactNodeReactElement有什么区别?
  2. 为什么类组件的render方法返回ReactNode,而函数组件返回ReactElement?
  3. 如何针对null解决此问题?
  1. What is the difference between JSX.Element, ReactNode and ReactElement?
  2. Why do the render methods of class components return ReactNode, but function components return ReactElement?
  3. How do I solve this with respect to null?

推荐答案

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

A ReactElement is an object with a type and props.

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

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

A ReactNode is a ReactElement, a ReactFragment, a string, a number or an array of ReactNodes, or null, or undefined, or a boolean:

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的泛型类型是任意类型.它存在,因为各种库都可以以自己的方式实现JSX,因此JSX是一个全局命名空间,然后由该库进行设置,React对其进行如下设置:

JSX.Element is a ReactElement, with the generic type for props and type being any. It exists, as various libraries can implement JSX in their own way, therefore JSX is a global namespace that then gets set by the library, React sets it like this:

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

例如:

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

事实上,它们确实返回了不同的东西. Component的回报:

Indeed, they do return different things. Components return:

 render(): ReactNode;

函数是无状态组件":

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

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

与react一样,将其键入为ReactElement | null.或者让Typescript推断类型.

Type it as ReactElement | null just as react does. Or let Typescript infer the type.

这篇关于什么时候使用JSX.Element vs ReactNode vs ReactElement?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-27 10:51