处理反应子项时,类型“Element[]”缺少以下属性

Jim*_*mmy 4 typescript reactjs

我有一个父组件,它将其子组件提供给子组件。子组件可以是节点或节点数组,并且根据它是节点还是节点数组,ChildComponent 中的子组件的呈现方式有所不同。但是,当我在 ParentComponent 中渲染 ChildComponent 时,出现以下 Typescript 错误:

\n
\n

TS2786:“ChildComponent”不能用作 JSX 组件。\xc2\xa0\xc2\xa0其返回类型\'Element | Element[]\' 不是有效的 JSX 元素。\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0Type \'Element[]\' 缺少类型 \'Element\' 中的以下属性: type、props、key

\n
\n

请参阅下面的代码。如何渲染 ChildComponent 而不出现任何 Typescript 错误?谢谢!

\n
import React from \'react\';\nimport styles from \'./component.scss\';\n\ninterface Props {\n  children: React.ReactChildren;\n}\n\nconst ChildComponent = ({ children }: Props): JSX.Element | JSX.Element[] => {\n  if (React.Children.count(children)) {\n    return React.Children.map(children, (child) => (\n      <div className={styles.childContainer}>{child}</div>\n    ));\n  }\n\n  return <div className={styles.singleContainer}>{children}</div>;\n};\n\nconst ParentComponent: React.FC<Props> = ({ children }) => (\n  <div className={styles.container}>\n    <ChildComponent>{children}</ChildComponent>\n  </div>\n);\n\nexport default ParentComponent;\n
Run Code Online (Sandbox Code Playgroud)\n

在此输入图像描述

\n

Aje*_*hah 9

在您当前的代码中,返回类型是JSX.Element[]来自if块(不正确)但来自部分JSX.Element正确else) 。这就是您所看到的错误的原因。

要修复此问题,您需要返回单个 JSX 表达式ChildComponent因为“JSX 表达式必须有一个父元素”。

您可以使用父元素,例如divspan或简单地使用React.Fragment(简写<></>):

const ChildComponent = ({ children }: Props) => {
  if (React.Children.count(children)) {
    return (
      <>  // HERE
        {React.Children.map(children, (child) => (
          <div className={styles.childContainer}>{child}</div>
        ))}
      </>
    );
  }
  return <div className={styles.singleContainer}>{children}</div>;
};
Run Code Online (Sandbox Code Playgroud)

并且children类型应该ReactNode代替ReactChildren

interface Props {
  children: React.ReactNode;
}
Run Code Online (Sandbox Code Playgroud)

因为这些是两种类型的定义:

type ReactNode = ReactChild | ReactFragment | ReactPortal | boolean | null | undefined;

interface ReactChildren {
  map<T, C>(children: C | C[], fn: (child: C, index: number) => T):
      C extends null | undefined ? C : Array<Exclude<T, boolean | null | undefined>>;
  forEach<C>(children: C | C[], fn: (child: C, index: number) => void): void;
  count(children: any): number;
  only<C>(children: C): C extends any[] ? never : C;
  toArray(children: ReactNode | ReactNode[]): Array<Exclude<ReactNode, boolean | null | undefined>>;
}
Run Code Online (Sandbox Code Playgroud)

另外,我建议不要使用 React.FC

这是一个演示

编辑:

PS:else 块<div className={styles.singleContainer}>{children}</div>if条件 withcount并不是真正需要的。