当前栏目
React报错之JSX element type does not have any construct or call signatures
正文从这开始~
总览
当我们试图将元素或react组件作为属性传递给另一个组件,但是属性的类型声明错误时,会产生"JSX element type does not have any construct or call signatures"错误。为了解决该错误,可以使用React.ElementType
类型。
这里有个例子来展示错误是如何发生的。
// App.tsx
import React from 'react';
interface Props {
comp: JSX.Element;
}
const Wrapper: React.FunctionComponent<Props> = props => {
const {comp: Comp} = props;
// ⛔️ JSX element type 'Comp' does not have any construct or call signatures.ts(2604)
return (
<div>
<Comp name="James" />
</div>
);
};
const App: React.FunctionComponent = () => {
const heading = ({name}: {name: string}) => <h2>Hello {name}</h2>;
return (
<div>
<Wrapper comp={heading} />
</div>
);
};
export default App;
我们尝试将一个React组件作为属性传递给Wrapper
组件,但我们将该React组件的类型声明为JSX.Element
。
React.ElementType
为了解决该错误,将属性的类型声明为React.ElementType
。
// App.tsx
import React from 'react';
interface Props {
comp: React.ElementType; // ?️ type it as React.ElementType
}
const Wrapper: React.FunctionComponent<Props> = props => {
// ?️ component names must start with capital letter
const {comp: Comp} = props;
return (
<div>
<Comp name="James" />
</div>
);
};
const App: React.FunctionComponent = () => {
// ?️ takes a name prop
const heading = ({name}: {name: string}) => <h2>Hello {name}</h2>;
return (
<div>
<Wrapper comp={heading} />
</div>
);
};
export default App;
请注意,
React.ElementType
可以为元素期望的属性类型传递一个泛型。
在这个例子中,我们必须传递给它一个具有字符串类型的name
属性的对象,因为那是heading
组件接收的属性。
// App.tsx
import React from 'react';
interface Props {
// ✅ explicitly type props comp takes
comp: React.ElementType<{name: string}>;
}
const Wrapper: React.FunctionComponent<Props> = props => {
// ?️ component names must start with capital letter
const {comp: Comp} = props;
return (
<div>
<Comp name="James" />
</div>
);
};
const App: React.FunctionComponent = () => {
const heading = ({name}: {name: string}) => <h2>Hello {name}</h2>;
return (
<div>
<Wrapper comp={heading} />
</div>
);
};
export default App;
现在我们显式地声明了元素在使用时所接受的comp
属性的类型。这有助于我们在向组件传递属性时利用IDE的自动完成功能。
我们也可以使用React.ComponentType
,但这样我们就需要对属性声明类型。
// App.tsx
import React from 'react';
interface Props {
// ?️ now using React.ComponentType ?️
comp: React.ComponentType<{name: string}>;
}
const Wrapper: React.FunctionComponent<Props> = props => {
// ?️ component names must start with capital letter
const {comp: Comp} = props;
return (
<div>
<Comp name="James" />
</div>
);
};
const App: React.FunctionComponent = () => {
const heading = ({name}: {name: string}) => <h2>Hello {name}</h2>;
return (
<div>
<Wrapper comp={heading} />
</div>
);
};
export default App;
React.ComponentType
中的泛型不能默认为any
类型,因此我们需要显示地声明属性的类型。
传递JSX元素
如果你需要将JSX元素作为属性传递给组件,并且不是一个真正的组件,那么使用JSX.Element
类型就是正确的。
// App.tsx
import React from 'react';
interface Props {
// ?️ using JSX.Element type
comp: JSX.Element;
}
const Wrapper: React.FunctionComponent<Props> = props => {
const {comp: Comp} = props;
// ?️ use as {Comp}
return <div>{Comp}</div>;
};
const App: React.FunctionComponent = () => {
const Heading = ({name}: {name: string}) => <h2>Hello {name}</h2>;
// ?️ we are passing an actual JSX element
// because we didn't pass it as comp={Heading}
return (
<div>
<Wrapper comp={<Heading name="James" />} />
</div>
);
};
export default App;
我们将comp
属性的类型声明为JSX.Element
,因为我们传递了一个真正的JSX元素(不是组件)到Wrapper
组件上。
我们传递了一个JSX元素,是因为我们将comp={<Heading />}
作为属性进行传递,而不是comp={(props) => <h2>Hello world</h2>}
。
需要注意的是,在第一种情况下,我们传递的是一个JSX元素属性。而在第二种情况下,我们传递的是一个返回JSX元素的函数(一个功能组件)。
在Wrapper组件中,我们不应尝试使用JSX元素作为组件。比如说,不要这么写<Comp />
,而要这么写{Comp}
。
我们没有传递一个真正的组件作为属性,我们传递的是一个JSX元素,所以它不应该作为一个组件使用。
更新类型包
如果前面的建议都没有帮助,试着通过运行以下命令来更新你的React类型的版本。
# ?️ with NPM
npm install react@latest react-dom@latest
npm install --save-dev @types/react@latest @types/react-dom@latest
# ----------------------------------------------
# ?️ with YARN
yarn add react@latest react-dom@latest
yarn add @types/react@latest @types/react-dom@latest --dev
相关文章
- React报错之Type '() => JSX.Element[]' is not assignable to type FunctionComponent
- React报错之JSX element type does not have any construct or call signatures
- React报错之组件不能作为JSX组件使用
- 理解JavaScript中的window对象
- 让Node项目支持可扩展的环境配置
- 使用 DevTools 加速调试 Node.js 应用程序
- 讲述JSON Web Token(概念)
- ?RxJs合并接口应用案例
- 如何让Node服务实现自动重启
- 使用PlopJs让开发变得更高效
- 上手JavaScript基准测试
- 【NodeJs】启动本地服务遭遇端口占用怎么办⁉️
- 【Ajv】JSON Schema Validator
- Vuejs 设计与实现笔记(一)
- Java-Jsp是什么原理又是什么
- Java-Jsp的一些语法与指令
- js正则表达式转义字符-4. 正则表达式的使用
- js正则表达式转义字符-【JavaScript正则表达式RegExp】
- 【全网最全】springboot整合JSR303参数校验与全局异常处理
- 安装typescript环境并开启VSCode自动监视编译ts文件为js文件