代码之家  ›  专栏  ›  技术社区  ›  Naresh

类型错误:JSX元素类型{}| null | undefined'不是JSX元素的构造函数

  •  0
  • Naresh  · 技术社区  · 7 年前

    我有一个叫React的组件 HandleQuery 它处理Apollo GraphQL查询的结果:

    import React, { ReactNode } from 'react';
    
    import { CenteredMessage } from './centered-message';
    
    export interface HandleQueryProps {
        loading: boolean,
        error?: Error,
        children: ReactNode
    }
    
    export const HandleQuery = ({ loading, error, children }: HandleQueryProps) => {
        if (loading) {
            return <CenteredMessage>Loading...</CenteredMessage>;
        }
    
        if (error) {
            return <CenteredMessage>{error.message}</CenteredMessage>;
        }
    
        return children;
    };
    

    当此组件在另一个组件中使用时,它不会编译:

    import React from 'react';
    
    import { useQuery } from 'react-apollo-hooks';
    import gql from 'graphql-tag';
    import { HandleQuery } from '..';
    import { MutationType } from '../../graphql-types';
    import { AuthorsPanel } from './authors-panel';
    import { GET_AUTHORS } from './authors-queries';
    import { AuthorMutated } from './__generated__/AuthorMutated';
    
    export class AuthorsContainer extends React.Component {
        render() {
            const { loading, error, data } = useQuery(GET_AUTHORS);
            return (
                <!-- THIS LINE PRODUCES A COMPILER ERROR -->
                <HandleQuery loading={loading} error={error}>
                    <AuthorsPanel data={data} />
                </HandleQuery>
            );
        }
    }
    

    手柄查询 以上产生以下错误:

    类型错误:JSX元素类型{}| null | undefined'不是JSX元素的构造函数。

    这是什么意思?我怎样才能摆脱它?

    将AuthorsContainer转换为函数组件不会消除错误:

    export const AuthorsContainer = () => {
        const { loading, error, data } = useQuery(GET_AUTHORS);
        return (
            <HandleQuery loading={loading} error={error}>
                <AuthorsPanel data={data} />
            </HandleQuery>
        );
    };
    

    更新2

    import React from 'react';
    
    import { CenteredMessage } from './centered-message';
    
    export interface HandleQueryProps {
        loading: boolean;
        error?: Error;
    }
    
    export const HandleQuery: React.FC<HandleQueryProps> = ({
        loading,
        error,
        children
    }) => {
        if (loading) {
            return <CenteredMessage>Loading...</CenteredMessage>;
        }
    
        if (error) {
            return <CenteredMessage>{error.message}</CenteredMessage>;
        }
    
        return children;
    };
    

    现在容器组件上的错误已经消失,但是在 手柄查询

    Type error: Type '({ loading, error, children }: PropsWithChildren<HandleQueryProps>) => {} | null | undefined' is not assignable to type 'FunctionComponent<HandleQueryProps>'.
      Type '{} | null | undefined' is not assignable to type 'ReactElement<any, string | ((props: any) => ReactElement<any, string | ... | (new (props: any) => Component<any, any, any>)> | null) | (new (props: any) => Component<any, any, any>)> | null'.
        Type 'undefined' is not assignable to type 'ReactElement<any, string | ((props: any) => ReactElement<any, string | ... | (new (props: any) => Component<any, any, any>)> | null) | (new (props: any) => Component<any, any, any>)> | null'.  TS2322
    
    0 回复  |  直到 7 年前
        1
  •  26
  •   FredyC    7 年前

    关于ReactNode存在一个长期问题。我不明白具体细节,但这是打字字体本身固有的东西,正在研究中。

    不管怎样,解决办法都应该很容易。不要将ReactNode与功能组件一起使用:)的 children prop隐式包含在反应.FC类型。

    同样的问题也出现在返乡儿童身上。它可以通过包装来克服 <React.Fragment> <div> 如果您愿意,但因为这只是一个类型错误,您可以说服TypeScript您知道自己在做什么:)

    import React, { ReactNode } from 'react';
    
    import { CenteredMessage } from './centered-message';
    
    export interface HandleQueryProps {
        loading: boolean,
        error?: Error,
    }
    
    export const HandleQuery: React.FC<HandleQueryProps> = ({ loading, error, children }) => {
        if (loading) {
            return <CenteredMessage>Loading...</CenteredMessage>;
        }
    
        if (error) {
            return <CenteredMessage>{error.message}</CenteredMessage>;
        }
    
        return children as ReactElement<any>;
    };
    
        2
  •  2
  •   alexojegu    6 年前

    在这种情况下,可以更简单地定义 children ReactElement 如果我没有回避什么。

    export interface HandleQueryProps {
        loading: boolean,
        error?: ApolloError,
        children: ReactElement
    }
    
        3
  •  0
  •   SwissCodeMen dgzornoza    6 年前

    rm -rf node_modules && rm yarn.lock && yarn

    推荐文章