我有一个非常简单的功能组件,如下所示
import * as React from 'react';
export interface AuxProps {
children: React.ReactNode
}
const aux = (props: AuxProps) => props.children;
export default aux;
和另一个组件
import * as React from "react";
export interface LayoutProps {
children: React.ReactNode
}
const layout = (props: LayoutProps) => (
<Aux>
<div>Toolbar, SideDrawer, Backdrop</div>
<main>
{props.children}
</main>
<Aux/>
);
export default layout;
我不断遇到以下错误:
[ts] JSX元素类型'ReactNode'不是JSX元素的构造函数。 类型'undefined'不能分配给'ElementClass'类型。 [2605]
如何正确输入?
答案 0 :(得分:23)
您可以使用ReactChildren
和ReactChild
:
import React, { ReactChildren, ReactChild } from 'react';
interface AuxProps {
children: ReactChild | ReactChildren;
}
const Aux = ({ children }: AuxProps) => (<div>{children}</div>);
export default Aux;
答案 1 :(得分:17)
children: React.ReactNode
答案 2 :(得分:16)
您也可以使用React.PropsWithChildren<P>
。
type ComponentWithChildProps = React.PropsWithChildren<{example?: string}>;
答案 3 :(得分:8)
在TypeScript中,功能组件的返回类型限于JSXElement | null
。这是当前的类型限制,即纯React allows more返回类型。
您可以使用类型断言或片段作为解决方法:
const Aux = (props: AuxProps) => <>props.children</>;
const Aux2 = (props: AuxProps) => props.children as ReactElement;
ReactNode
children: React.ReactNode
提供强类型,则 Aux
可能不是最佳选择。
几乎所有内容都可以分配给当前的ReactNode
类型,这等效于{} | undefined | null
。对于您的案件,更安全的类型可能是:
interface AuxProps {
children: ReactElement | ReactElement[]
}
示例:
鉴于Aux
需要像children
那样的React元素,我们无意中添加了一个string
。与above solution相比,ReactNode
会出错-看一下链接的游乐场。
类型为children
的非JSX道具也很有用,例如Render Prop回调。
答案 4 :(得分:5)
为了在您的JSX中使用XElement
,它必须是一个返回<Aux>
的函数。这就是功能组件的定义。
但是,当前定义为返回ReactElement<any> | null
的函数,这是一个更广泛的类型。正如React输入所说的那样:
React.ReactNode
通过将返回的值包装到React Fragment(type ReactNode = ReactChild | ReactFragment | ReactPortal | boolean | null | undefined;
)中,确保不需要的类型被中和:
<></>
答案 5 :(得分:5)
这对我有用:
interface Props {
children: JSX.Element[] | JSX.Element
}
答案 6 :(得分:5)
我正在使用以下内容
type Props = { children: React.ReactNode };
const MyComponent: React.FC<Props> = ({children}) => {
return (
<div>
{ children }
</div>
);
export default MyComponent;
答案 7 :(得分:4)
您可以这样声明组件:
const MyComponent: React.FunctionComponent = (props) => {
return props.children;
}
答案 8 :(得分:4)
这一直对我有用:
type Props = {
children: JSX.Element;
};
答案 9 :(得分:3)
这些答案似乎已过时-React现在具有内置类型PropsWithChildren<{}>
。它的定义类似于此页面上的一些正确答案:
type PropsWithChildren<P> = P & { children?: ReactNode };
答案 10 :(得分:3)
React Node
是以下类型之一:
Boolean
(将被忽略)null
或undefined
(将被忽略)Number
String
React element
(JSX
的结果)答案 11 :(得分:2)
作为一种包含子代的类型,我正在使用:
type ChildrenContainer = Pick<JSX.IntrinsicElements["div"], "children">
此子容器类型具有足够的通用性,可以支持所有不同的情况,并且与ReactJS API保持一致。
因此,对于您的示例,它类似于:
const layout = ({ children }: ChildrenContainer) => (
<Aux>
<div>Toolbar, SideDrawer, Backdrop</div>
<main>
{children}
</main>
<Aux/>
)
答案 12 :(得分:2)
您也可以使用 JSX.ElementChildrenAttribute
export default function Layout({children}: JSX.ElementChildrenAttribute) {
return <div>
{children}
</div>
}
答案 13 :(得分:0)
从TypeScript网站:https://github.com/Microsoft/TypeScript/issues/6471
建议的做法是将props类型写为{children ?: 任何}
对我有用。子节点可以有很多不同的东西,因此显式键入可能会遗漏大小写。
这里有一个有关后续问题的较长讨论:https://github.com/Microsoft/TypeScript/issues/13618,但是任何方法仍然有效。
答案 14 :(得分:0)
通用查找任何类型的方法是示例。打字稿的妙处在于,只要您拥有正确的@types/
文件,您就可以访问所有类型。
我自己想回答这个问题,我只是想到了具有children
道具的组件react用法。我想到的第一件事是? <div />
怎么样?
您需要做的就是打开vscode并使用.tsx
在react项目中创建一个新的@types/react
文件。
import React from 'react';
export default () => (
<div children={'test'} />
);
将鼠标悬停在children
道具上会显示类型。而且您知道吗-它的类型是 ReactNode
(不需要ReactNode[]
)。
然后,如果您单击类型定义,则会直接进入children
界面中的DOMAttributes
定义。
// node_modules/@types/react/index.d.ts
interface DOMAttributes<T> {
children?: ReactNode;
...
}
注意:此过程应用于查找任何未知类型!他们都在那里等着你找到他们:)
答案 15 :(得分:-1)
反应组件应具有单个包装器节点或返回节点数组。
您的<Aux>...</Aux>
组件有两个节点div
和main
。
尝试将孩子包装在div
组件中的Aux
中。
import * as React from 'react';
export interface AuxProps {
children: React.ReactNode
}
const aux = (props: AuxProps) => (<div>{props.children}</div>);
export default aux;