JSX 元素没有构造函数?解析 TypeScript 错误

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言:你的组件“沉默不语”,因为它不懂得如何“诞生”

你正在使用 TypeScript 和 React 进行开发,一切进展顺利。然后——砰!——编译器向你抛出一个神秘的消息:

JSX 元素类型 'MyComponent' 没有任何构造或调用签名。

是不是很眼熟?如果你是新手,这个错误可能看起来像是来自平行世界的咒语。但别急着惊慌。实际上,这很简单:TypeScript 告诉你,你试图用作 JSX 组件的东西,实际上既不是可以“调用”的函数,也不是可以“构造”的类。

在本文中,我们将用通俗易懂的方式剖析这个错误:它为什么会出现,如何修复,以及这些“构造或调用签名”到底是什么意思。来吧——我们将愉快地通过示例来理解它!



“构造或调用签名”是什么意思?

让我们把 JSX 组件想象成一家餐厅。你走进去,在桌旁坐下(传递 props),然后等待上菜(返回 JSX)。但如果餐厅正在装修或者根本不存在,你就无法点餐。

在 TypeScript 中,“构造签名”是指一个类能够通过 new 被调用(像构造函数一样)。“调用签名”是指一个函数能够被直接调用。React 中的 JSX 组件可以是函数,也可以是类。如果 TypeScript 在你的“组件”上看不到这两者中的任何一个——它就会报错。

典型情况:

// 错误const MyComponent = someObject;// <MyComponent /> — 报错!

// 正确const MyComponent: React.FC<Props> = (props) => { return <div>你好</div>;};// <MyComponent /> — 正常工作

当你试图在 JSX 中使用不是函数或类的东西时,就会出现这个错误。例如,字符串、数字、对象或未初始化的变量。



错误的 5 大原因(附 TypeScript 代码示例)

我们来分析一下最常见的几种让你踩坑的场景。针对每种情况,我都会展示问题是什么以及如何修复。



1. 组件是一个对象,而不是函数

最常见的陷阱。你导入了一些东西,以为它是一个组件,但实际上它是一个包含数据或配置的普通对象。

// ❌ 错误import userData from './userData';// userData = { name: '安娜', age: 25 }function App() {  return <userData />; // userData — 是对象,不是组件!}

// ✅ 修复import UserCard from './UserCard';function App() { return <UserCard user={userData} />;}

如何检查: 将鼠标悬停在 IDE 中的变量上。如果 TypeScript 显示类型为 object、Record<string, any> 或类似的不包含 () => JSX.Element 的类型——那它就不是组件。



2. 组件是一个字符串或数字

有时由于疏忽,你可能会在 JSX 中传递一个原始类型的字面量或变量。

// ❌ 错误const greeting = "你好,世界!";function App() {  return <greeting />; // greeting — 是 string 类型}

// ✅ 修复function App() { return <h1>{greeting}</h1>; // 将其用作文本,而不是组件}


3. 组件导入方式不正确

如果你使用了 export default 并且没有用花括号导入,但导出是命名导出——你会得到 undefined。而在 JSX 中使用 undefined 正是导致这个错误的原因。

// 在 Button.tsx 文件中export const Button = () => <button>点击</button>;// 缺少 export default!

// ❌ 错误import Button from './Button'; // Button = undefinedfunction App() { return <Button />;}

// ✅ 修复import { Button } from './Button'; // 命名导入// 或者在 Button.tsx 中添加 export default

博客

书籍推荐