reactjs - 组件不能用作 JSX 组件。它的返回类型 'Element[]' 不是有效的 JSX 元素

标签 reactjs typescript

我目前在 Todos 上遇到以下错误内部组件 TodoApp.tsx : 'Todos' 不能用作 JSX 组件。
它的返回类型 'Element[]' 不是有效的 JSX 元素。
类型“元素 []”缺少类型“元素”的以下属性:类型、 Prop 、键
这是我的文件夹结构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)如下:
interface TodoProps {
  text: string;
  completed: boolean;
  id: string;
}
已经尝试过用片段包装 map 项的修复方法,但我仍然无法使其工作。到目前为止,唯一要解决的问题是在 Todos.tsx 的顶部声明像这样 function 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 : 片段。
Playground

关于reactjs - 组件不能用作 JSX 组件。它的返回类型 'Element[]' 不是有效的 JSX 元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62702485/

相关文章:

javascript - 通过 React.cloneElement 维护组件引用

javascript - React Key 在不同元素上的唯一性

angular - 模板中对象的输入在 Angular 10 中给出错误 "Property is used before its initialization"

reactjs - react Action ,ESLint : Argument 'dispatch' should be typed with a non-any type

typescript - 获取键入的对象中的属性或字段的名称

reactjs - 安装时 react Spring 错误

reactjs - 错误 TS2430 : Interface 'RcFile' incorrectly extends interface 'File' in antd

javascript - 如何恢复另一个组件的值?

angular - 如何知道要输入字符的位置?

javascript - 更新搜索结果的计数并根据用户在对象数组中搜索的次数更改选择