【发布时间】:2019-07-21 04:03:45
【问题描述】:
我有一个名为 HandleQuery 的 React 组件来处理 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>
);
}
}
上面使用HandleQuery会产生以下错误:
类型错误:JSX 元素类型'{} |空 | undefined' 不是 JSX 元素的构造函数。 类型“未定义”不可分配给类型“元素 |空值'。 TS2605
这是什么意思,我该如何摆脱它?
更新
将 AuthorsContainer 转换为函数组件并不能消除错误:
export const AuthorsContainer = () => {
const { loading, error, data } = useQuery(GET_AUTHORS);
return (
<HandleQuery loading={loading} error={error}>
<AuthorsPanel data={data} />
</HandleQuery>
);
};
更新 2 来自@FredyC 的实施建议:
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;
};
现在容器组件上的错误已经消失,但是HandleQuery组件上弹出了一个新的编译器错误:
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
【问题讨论】:
-
开始
console.log()ing 一切。找出什么是空的。从看起来HandleQuery看来是未定义的。也许你的意思是import { HandleQuery } from '../'? -
@FrankerZ - 这是 compile-time 错误(TSnnnn 是 TypeScript 编译器错误代码),而不是运行时错误。 (OP 还方便地说“这一行会产生编译器错误”,尽管在他的情况下,他使用了全部大写。)
-
类中可以使用钩子吗?我以为它们只是功能组件?
-
HandleQuery 已正确导入。它在 ../index.tsx 中定义
-
请阅读 Hooks 常见问题解答。它说“你不能在类组件中使用 Hooks”。让我尝试将其转换为函数组件。
标签: reactjs typescript react-apollo