[英]Component cannot be used as a JSX component. Its return type 'Element | undefined' is not a valid JSX element
[英]Component cannot be used as a JSX component. Its return type 'Element[]' is not a valid JSX element
我目前在TodoApp.tsx
中的Todos
组件上收到以下错误:“Todos”不能用作 JSX 组件。 它的返回类型“Element[]”不是有效的 JSX 元素。 类型“Element[]”缺少类型“Element”中的以下属性:type、props、key
这是我的文件夹结构
TodoApp.tsx
function TodoApp() {
return (
<Body>
<AppDiv>
<Form />
<Todos />
<Footer />
</AppDiv>
</Body>
);
}
Todos.tsx
function Todos(): JSX.Element[] {
const todos = useSelector((state: RootState) => state.todos);
const footer = useSelector((state: RootState) => state.footer);
if (footer.hideAll) {
if (footer.showCompleted) {
return todos
.filter((todo) => !todo.completed)
.map((todo: any) => (
<>
<ul>
<Todo todo={todo} />
</ul>
</>
));
}
return todos.map((todo) => (
<>
<div>
<Todo todo={todo} />
</div>
</>
));
}
return todos.map(() => (
<>
<div></div>
</>
));
}
Todo.tsx
type Todo = {
todo: TodoProps;
};
const Todo = ({ todo }: Todo) : JSX.Element => {
const [isEditing, edit] = useState<boolean>(false);
const dispatch = useDispatch();
if (!isEditing) {
return (
<TodoDiv>
<Li
key={todo.id}
completed={todo.completed}
onClick={() => dispatch(completeTodo(todo.id))}
// style={{
// textDecoration: todo.completed ? "line-through" : "none"
// }}
>
{todo.text}
</Li>
<TodoBttns>
<Button edit onClick={() => edit(!isEditing)}>
<img src={editBttn} alt="Edit Button" />
</Button>
<Button delete onClick={() => dispatch(deleteTodo(todo.id))}>
<img src={deleteBttn} alt="Delete Button" />
</Button>
</TodoBttns>
</TodoDiv>
);
} else {
return (
<FormEdit>
<InputForm key={todo.id} {...{ todo, edit }} />
</FormEdit>
);
}
};
TodoProps 接口如下:
interface TodoProps {
text: string;
completed: boolean;
id: string;
}
已经尝试用片段包装 map 项目的修复,但我仍然无法使其工作。 到目前为止唯一能解决这个问题的是在Todos.tsx
的顶部声明这个function Todos(): any
附带说明:我正在使用样式化组件,但我认为该问题与库无关。
组件需要返回单个根元素。 您可以使用片段将 package 元素数组作为单个元素,通过将片段用作单个根元素。
所以这什么都不做:
function Todos(): JSX.Element {
return todos.map(todo => (
<>
<li>{todo.task}</li>
</>
)
}
因为它现在返回[<><li/></>, <><li/></>, ...]
的数组。 该片段需要是单个根元素。
您需要像这样使用片段:
function Todos(): JSX.Element {
return <>{
todos.map(todo => <li>{todo.task}</li>)
}</>
}
您将所有返回的 JSX 嵌套在一个片段中。
使用这种模式,你最终可能会得到这样的结果:
function Todos(): JSX.Element {
const todos = useSelector((state: RootState) => state.todos);
const footer = useSelector((state: RootState) => state.footer);
if (footer.hideAll) {
if (footer.showCompleted) {
return <>{
todos
.filter((todo) => !todo.completed)
.map((todo: any) => (
<ul>
<Todo todo={todo} />
</ul>
))
}</>
}
return <>{
todos.map((todo) => (
<div>
<Todo todo={todo} />
</div>
))
}</>
}
return <>{
todos.map(() => (
<div></div>
))
}</>
}
// Works without error
<Todos />
注意每个 return 语句如何只返回一个JSX.Element
:片段。
您需要返回一个 JSX 元素,而不是一个数组。 包装整个组件是一种解决方案,但您需要在映射/过滤器 function 之外进行。
Todos.tsx
function Todos(): JSX.Element {
const todos = useSelector((state: RootState) => state.todos);
const footer = useSelector((state: RootState) => state.footer);
if (footer.hideAll) {
if (footer.showCompleted) {
return (
<>
{todos.filter((todo) => !todo.completed).map((todo: any) => (
<ul>
<Todo todo={todo} />
</ul>
));
}
</>
}
return (
<>
{todos.map((todo) => (
<div>
<Todo todo={todo} />
</div>
));
}
</>
}
return (
<>{todos.map(() => <div />)}</>
);
}
如果有人遇到 React + Typescript 堆栈的问题,请尝试在 tsconfig.json 中添加以下设置。 它对我有用。
“allowSyntheticDefaultImports”:真
就我而言,这是一个被遗忘的导入。 基本上复制粘贴了我的一些代码并忘记导入其中一个组件,这是我得到的错误消息。
您可能已经安装(并且可能失败)新的 package,这也可能导致此错误。
如果是这种情况(您最近安装并失败或取消了一个包),您可以删除node_modules
并运行npm i
或yarn install
然后重试。
您需要为 react 安装类型npm install @types/react
或yarn add @types/react
当您使用switch case
语法呈现组件时,有时会发生此错误。
例如:
switch (loading) {
case "pending":
return <span>Pending</span>;
case "succeeded":
return <span>Succeeded</span>;
case "failed":
return <span>Failed</span>;
有时您的加载状态可能会错误地具有您未在case
中指定的值,因此您的组件将返回undefined
。 因此,您应该添加一个default
值:
default: return <span>¯\_(ツ)_/¯</span>;
对于有人升级到更高版本的React
的场景,例如, 16
-> 17
,它可能会开始发生。
现在,在您的项目中查找@types/react
时,您会注意到许多npm
包具有@types/react: "*",
。 在这种情况下,摆脱问题的解决方案是添加到您的package.json
:
"resolutions": {
"@types/react": "^17.0.38"
}
关于这个错误,我面临同样的问题。 我将以下代码添加到我的package.json文件中。
"resolutions": {
"@types/react": "17.0.2",
"@types/react-dom": "17.0.2",
"graphql": "^16.5.0"
},
然后,在终端上运行yarn install
。
这个对我有用。
这个答案与 react-native 上的相同问题有关。将 typescript 添加到我新创建的 react-native 应用程序并将 App.js 移动到 App.tsx,我遇到了名为 Section 的组件的相同错误。 我的解决方案是组件类型React.Fc<{...}>
。 当所有错误都消失并且我的应用程序按预期启动时,这是修复后有问题的部分组件。
import React, { ReactNode } from 'react';
import {
SafeAreaView,
ScrollView,
StatusBar,
StyleSheet,
Text,
useColorScheme,
View,
} from 'react-native';
import {
Colors,
DebugInstructions,
Header,
LearnMoreLinks,
ReloadInstructions,
} from 'react-native/Libraries/NewAppScreen';
const Section: React.FC<{
children: ReactNode;
title: string;
}> = ({children, title}) => {
const isDarkMode = useColorScheme() === 'dark';
return (
<View style={styles.sectionContainer}>
<Text
style={[
styles.sectionTitle,
{
color: isDarkMode ? Colors.white : Colors.black,
},
]}>
{title}
</Text>
<Text
style={[
styles.sectionDescription,
{
color: isDarkMode ? Colors.light : Colors.dark,
},
]}>
{children}
</Text>
</View>
);
};
“组件不能用作 JSX 组件”错误的另一个常见原因是当我们从组件返回 JSX 元素或 null 以外的任何内容时,或者忘记返回值。
App 组件返回 undefined ,因为我们将 return 语句放在一行,将 JSX 代码放在下一行,而没有使用括号。
我们不允许从组件返回undefined ,所以错误发生了。
添加以下代码
"paths": {
"react": [ "./node_modules/@types/react" ]
}
到tsconfig.json
文件,在 compilerOptions
这是我的代码现在的样子:
{
"compilerOptions": {
"jsx":"react",
"strict": true,
"paths": {
"react": [ "./node_modules/@types/react" ]
}
}
}
它告诉 typescript 编译器,当遇到对“react”模块的引用时,它应该在“./node_modules/@types/react”目录中查找实际实现。
就我而言,我忘记在styled(PreviousStyledElement);
之后放回刻度线。 在我把它们放好之后,代码就开始工作了。
export const MyNewStyledElement = styled(PreviousStyledElement)``;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.