组件不能用作 JSX 组件.它的返回类型 'Element[]' 不是有效的 JSX 元素 [英] 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() {返回 (<身体><AppDiv><表格/><待办事项/><页脚/></AppDiv></身体>);}
Todos.tsx
function Todos(): JSX.Element[] {const todos = useSelector((state: RootState) => state.todos);const footer = useSelector((state: RootState) => state.footer);如果(页脚.hideAll){如果(footer.showCompleted){返回待办事项.filter((todo) => !todo.completed).map((todo: any) => (<><ul><Todo todo={todo}/></>));}返回 todos.map((todo) => (<><div><Todo todo={todo}/>
</>));}返回 todos.map(() => (<><div></div></>));}
Todo.tsx
type Todo = {待办事项:TodoProps;};const Todo = ({ todo }: Todo) : JSX.Element =>{const [isEditing, edit] = useState(false);const dispatch = useDispatch();如果 (!isEditing) {返回 (<TodoDiv><李键={todo.id}完成={todo.completed}onClick={() =>dispatch(completeTodo(todo.id))}//样式={{//textDecoration: todo.completed ?直通":无"//}}>{todo.text}<TodoBttns><按钮编辑 onClick={() =>编辑(!isEditing)}><img src={editBttn} alt=编辑按钮"/></按钮><按钮删除 onClick={() =>dispatch(deleteTodo(todo.id))}><img src={deleteBttn} alt=删除按钮"/></按钮></TodoBttns></TodoDiv>);} 别的 {返回 (<表格编辑><InputForm key={todo.id} {...{ todo, edit }}/></FormEdit>);}};
和 TodoProps 接口如下:
interface TodoProps {文本:字符串;完成:布尔值;id:字符串;}
已经尝试了用片段包裹地图项目的修复,但我仍然无法使其工作.目前唯一解决这个问题的是在 Todos.tsx
的顶部声明为这个 function Todos(): any
附带说明:我使用的是样式化组件,但我认为问题与库无关.
组件需要返回单个根元素.通过将片段用作单个根元素,您可以使用片段将元素数组打包为单个元素.
所以这什么都不做:
function Todos(): JSX.Element {返回 todos.map(todo => (<><li>{todo.task}</li></>)}
因为它现在返回一个 [<>>, <><li/></>, ...]代码>.该片段必须是单个根元素.
你需要像这样使用片段:
function Todos(): JSX.Element {返回 <>{todos.map(todo => {todo.task} )}</>}
您将所有返回的 JSX 嵌套在一个片段中.
使用这种模式,你可能会得到这样的结果:
function Todos(): JSX.Element {const todos = useSelector((state: RootState) => state.todos);const footer = useSelector((state: RootState) => state.footer);如果(页脚.hideAll){如果(footer.showCompleted){返回 <>{待办事项.filter((todo) => !todo.completed).map((todo: any) => (<ul><Todo todo={todo}/>))}</>}返回 <>{todos.map((todo) => (<div><Todo todo={todo}/>
))}</>}返回 <>{todos.map(() => (<div></div>))}</>}//工作没有错误<待办事项/>
注意每个 return 语句如何只返回一个 JSX.Element
:片段.
I'm currently getting the following error on the Todos
component inside TodoApp.tsx
: 'Todos' cannot be used as a JSX component.
Its return type 'Element[]' is not a valid JSX element.
Type 'Element[]' is missing the following properties from type 'Element': type, props, key
And this is my folder structure
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>
);
}
};
and the TodoProps interface is the following:
interface TodoProps {
text: string;
completed: boolean;
id: string;
}
already tried the fix of wraping the map items with fragments, but I still can't make it work. The only thing that as of now is fixing the issue is declaring at the top of Todos.tsx
as this function Todos(): any
As a side note: I'm using Styled Components, but I don't think the issue is related to the library.
A component needs to return a single root element. You can use fragments to package an array of elements as a single element, by using the fragment as that single root element.
So this does nothing:
function Todos(): JSX.Element {
return todos.map(todo => (
<>
<li>{todo.task}</li>
</>
)
}
Because it's now returning an array of [<><li/></>, <><li/></>, ...]
. That fragment needs to be the single root element.
You need to use the fragment like this:
function Todos(): JSX.Element {
return <>{
todos.map(todo => <li>{todo.task}</li>)
}</>
}
You nest all returned JSX in one single fragment.
Using that pattern you may end up with somehting like this:
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 />
Note how each return statement returns just one JSX.Element
: the fragment.
这篇关于组件不能用作 JSX 组件.它的返回类型 'Element[]' 不是有效的 JSX 元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!