Nar*_*esh 7 typescript reactjs react-apollo
我有一个称为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;
};
Run Code Online (Sandbox Code Playgroud)
当此组件在另一个组件中使用时,不会编译:
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>
);
}
}
Run Code Online (Sandbox Code Playgroud)
使用HandleQuery上述方法会产生以下错误:
类型错误:JSX元素类型'{} | 空| undefined'不是JSX元素的构造函数。类型'undefined'不能分配给类型'Element | 空值'。TS2605
这是什么意思,我该如何摆脱呢?
更新资料
将AuthorsContainer转换为功能组件并不能消除该错误:
export const AuthorsContainer = () => {
const { loading, error, data } = useQuery(GET_AUTHORS);
return (
<HandleQuery loading={loading} error={error}>
<AuthorsPanel data={data} />
</HandleQuery>
);
};
Run Code Online (Sandbox Code Playgroud)
更新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;
};
Run Code Online (Sandbox Code Playgroud)
现在,容器组件上的错误已消失,但是该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
Run Code Online (Sandbox Code Playgroud)
关于ReactNode有一个长期的问题。我不了解具体细节,但这是TypeScript本身的硬连线,正在开发中。
无论哪种方式,解决方案都应该很容易。不要将ReactNode与功能组件一起使用:)该children属性隐式包含在React.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>;
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2780 次 |
| 最近记录: |