我正在用React构建一个复合组件,我想强制只显示具有特定属性的子组件。
在下面的示例中,我创建了一个基本组件Trigger
,其显示名称为Trigger
。我希望组件SubMenuItem
能够使用属性displayName
查找Trigger
组件。问题是,当我尝试检查子元素Property 'displayName' does not exist on type 'string | number | ReactElement<any, string | JSXElementConstructor<any>> | Iterable<ReactNode> | ReactPortal'. Property 'displayName' does not exist on type 'string'.
的显示名称属性时,Typescript产生以下错误
另外,有人知道为了唯一标识的目的而将属性附加到组件是否是反模式吗?如果是,这是否意味着React不是为这种类型的复合模式构建的,其中组件能够识别哪些组件被传递给它。
string | number | React.ReactElement<any, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | React.ReactPortal
const Trigger = () => <button>Menu Trigger</button>
Trigger.displayName = 'Trigger'
export { Trigger }
import * as NavigationMenu from '@radix-ui/react-navigation-menu'
import React, { PropsWithChildren } from 'react'
const SubMenuItem = ({ children }: PropsWithChildren) => {
const childrenArray = React.Children.toArray(children)
const menuTrigger = childrenArray.filter(child => {
return child.displayName === 'Trigger'
})
return <NavigationMenu.Item>
{menuTrigger}
<ul>
<li><a href="#">route 1</a></li>
<li><a href="#">route 2</a></li>
</ul>
</NavigationMenu.Item>
}
尝试1利用ReactElement
接口的内置类型。不要将属性displayName
添加到Trigger
,而是执行Trigger.type = 'Trigger
。这将编译,但元素没有正确过滤。
const menuTrigger = childrenArray.filter(child => {
if (React.isValidElement(child) && child.type === 'Trigger') {
return true
}
})
型
引用的资源
1条答案
按热度按时间bihw5rsg1#
我发现
ReactElement.type
的类型是JSXElementConstructor<any>
。这意味着我们可以导入Trigger组件并检查child.type
是否与之等价。字符串