TypeScript 3:JSX 元素类型 'Component' 没有任何构造或调用签名。[2604]



我正试图将React.Component(或React.FunctionComponent(类型的变量传递到一个Route中,如下所示:

import React from 'react';
import { Route } from 'react-router-dom';
type PrivateRouteProps = {
component: React.Component | React.FunctionComponent;
isAuthenticated: boolean;
login: (...args: any[]) => any;
path: string;
};
const PrivateRoute: React.FunctionComponent<PrivateRouteProps> = ({
component: Component,
isAuthenticated,
login,
path,
...rest
}) => {
return (
<Route
path={path}
{...rest}
render={props => {
if (isAuthenticated) {
return <Component {...props} />;
} else {
login();
return null;
}
}}
/>
);
};

但我得到了这个错误:

JSX元素类型"Component"没有任何构造或调用签名。[2604]

我已经阅读了许多关于这个问题的其他线程,但它们似乎都处理了特定组件实现中出现的这个错误。我不能更改有问题的组件或以不同的方式导入它(就像公认的答案经常建议的那样(,因为它可以是任何组件。

我使用的是TypeScript 3.1.6、Babel Core 7.1和React 16.6.3。

使用"@types/react-router-dom": "^4.3.4""@types/react": "16.9.1"迟到,如果使用RouteProps,可能会出现同样的错误。

JSX元素类型"Component"没有任何构造或调用签名。[2604]

这是因为在RouteProps接口中,component被定义为可选的,因此它可能是未定义的。

export interface RouteProps {
location?: H.Location;
component?: React.ComponentType<RouteComponentProps<any>> | React.ComponentType<any>;
render?: ((props: RouteComponentProps<any>) => React.ReactNode);
children?: ((props: RouteChildrenProps<any>) => React.ReactNode) | React.ReactNode;
path?: string | string[];
exact?: boolean;
sensitive?: boolean;
strict?: boolean;
}

只需检查component是否是错误的就会修复它。

function PrivateRoute({ component: Component, ...rest }: RouteProps) {
if (!Component) return null;
return (
<Route
{...rest}
render={props =>
fakeAuth.isAuthenticated ? (
<Component {...props} />
) : (
<Redirect
to={{
pathname: "/login",
state: { from: props.location }
}}
/>
)
}
/>
);
}

我已经遇到过几次这种情况。试试这些:

  1. 将您的PrivateRoute键入为React.FC<Props>
  2. 将传入组件键入为React.ElementType

React类型的最终真相来自文档

编辑:React.ReactType(已弃用(->React.ElementType

甚至在派对后期,但对我有用的是:

interface PrivateRouteProps extends Omit<RouteProps, "component"> {
component: React.ElementType;
// any additional vars
}
PrivateRoute: React.FC<PrivateRouteProps> = ({
component: Component,
...rest
}) => {
// render code
}

这已经很晚了,但如果有人不想要解决方案而是想要解释,让我们用一个例子来演示这个错误

function PaymentPage(){

return <div>Payment Page</div>
}

假设我们想创建一个动态支付表单,如果查询参数是with=stripe,那么我们假设他想用stripe支付,如果是用razorpay,我们假设。。。等

然后我们做一些类似的事情

function PaymentPage(){
const router = useRouter;
const {with_} = router.query;
let GatewayComponent: Gateway | null = null;
switch(with_){
case 'stripe':
GatewayComponent = <StripeGateway/>;
break;
case 'razorpay':
GatewayComponent = <RazorpayGateway/>;
break;
}
return <GatewayComponent/>
}

运行这个,我们得到

JSX element type 'Component' does not have any construct or call signatures.

会发生什么?

什么是组件

  • 返回JSX.Element类型元素的构造函数

那么呢

  • 我们没有返回构造函数,我们返回constructor调用。这与假设GatewayComponent是构造函数相同,但它不是,它是一个包含JSX的变量

因此,基本上,期望x是任何类型的构造函数,无论是函数还是类,如果它是函数,那么函数就是呈现函数,如果是类,那么它需要一个呈现方法。

回到我们的问题

function PaymentPage(){
const router = useRouter;
const {with_} = router.query;
let gateway: Gateway | null = null;
switch(with_){
case 'stripe':
gateway = <StripeGateway/>;
break;
case 'razorpay':
gateway = <RazorpayGateway/>
break;
}
return <React.Fragment> {gateway} </React.Fragment>
}

因为网关持有JSX,而不是返回JSX 的构造函数

如果您想将其用作组件,该怎么办

function PaymentPage(){
const router = useRouter;
const {with} = router.query;
let GatewayComponent: Gateway | null = null;
switch(with_){
case 'stripe':
return () => <StripeGateway/>
case 'razorpay':
return () => <RazorpayGateway/>
}
return <GatewayComponent/>
}

现在它是一个构造函数,我们现在可以将它用作组件。

形式上,您传递的是构造函数,而不是实例。

<PrivateRoute路径="/>
Path在使用接口PrivateRouteProps时出错,然后我将其切换到

export type PrivateRouteProps = {
component: React.ElementType;
currentUser?: any;
} & RouteProps;```

下方的最终结果

import { Route, Redirect, RouteProps } from "react-router-dom";
export type PrivateRouteProps = {
component: React.ElementType;
currentUser?: any;
} & RouteProps;
const PrivateRoute: React.FC<PrivateRouteProps> = ({
component: Component,
currentUser,
...rest
}) => (
<Route
{...rest}
render={(props) =>
currentUser ? <Component {...props} /> : <Redirect to="/" />
}
/>
);

我能够通过如下键入我的组件来解决错误:

...
export function withApollo (PageComponent: () => JSX.Element) {
const WithApollo = <T extends object>(props: T) => {
...

最新更新