reactjs - 组件不能用作 JSX 组件。它的返回类型 'Element[]' 不是有效的 JSX 元素
问题描述
我目前在Todos
内部组件上遇到以下错误TodoApp.tsx
:“Todos”不能用作 JSX 组件。它的返回类型 'Element[]' 不是有效的 JSX 元素。类型“元素 []”缺少类型“元素”的以下属性:类型、道具、键
这是我的文件夹结构
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;
}
已经尝试过用片段包装地图项的修复方法,但我仍然无法使其工作。到目前为止,唯一要解决的问题是在顶部声明Todos.tsx
为 thisfunction Todos(): any
附带说明:我正在使用样式化组件,但我认为问题与库无关。
解决方案
组件需要返回单个根元素。通过将片段用作单个根元素,您可以使用片段将元素数组打包为单个元素。
所以这什么都不做:
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
:片段。
推荐阅读
- python - 管理 .txt 文件中的数据以将其存储到 Python 中的 SQLite3
- c# - 如何获取属性的值
- datagrid - OpenShift Online 上的 JDG - 尽管为角色分配了适当的权限,但出现 HotRodClientException
- postgresql - 如何恢复已删除的数据对称 ds
- python - 当前不支持错误对象数组 Python
- ios - 只能解析一些 JSON 数据,语法问题?
- javascript - 按下按钮时每秒执行一次javascript函数
- javascript - 为什么在 React 中使用 setState?
- c# - 如何实现这个 mvc 过滤器属性?
- selenium - Selenium - 避免获取验证码