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

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

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

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

  • JSX.ElementReactNodeReactElement有什么区别?
  • 为什么类组件的render方法返回ReactNode,而函数组件返回ReactElement
  • 如何针对null解决此问题?
  • 最佳答案



    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,未定义或 bool 值:
    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对其进行如下设置:
    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的返回:
     render(): ReactNode;
    

    函数是“无状态组件”:
     interface StatelessComponent<P = {}> {
        (props: P & { children?: ReactNode }, context?: any): ReactElement | null;
        // ... doesn't matter
    }
    

    这实际上是由于historical reasons引起的。



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

    source for the types

    10-06 08:13