我正在构建一个REACT
应用程序(带有TypeScript),并且遇到了一个问题,即哪种解决方案需要识别不同的REACT
子组件。基本上是这样的:
const RibbonTab: ReactFC<IRibbonTab> = (props) => {
return <p>{props.header}</p>
}
const Ribbon: ReactFC<IRibbon> = (props) => {
const ribbonTabs = props.children.ofType<RibbonTab>(); // This is what I'd like to accomplish.
return <>props.children</>;
}
我已经搜索了一段时间,许多(如果不是全部)可接受的答案(例如:only allow children of a specific type in a react component)将使用type.displayName
(this.props.children[child].type.displayName
)。不幸的是,也有人说displayName
在生产中可能会被缩小,所以我只是不能依靠它。
我发现的唯一方法是“强制”自己的显示名称。基本上,我创建一个接口IUniqueComponent
,然后将其扩展到应该可识别的每个组件。像这样:
interface IUniqueComponent {
displayNameForIdentification: string;
}
const RibbonTab: ReactFC<IRibbonTab extends IUniqueComponent> = (props) => { ... }
RibbonTab.defaultProps = { displayNameForIdentification: "RibbonTab" }
然后,使用React.Children.forEach
,我可以过滤孩子:
React.Children.forEach(props.children, (c) => {
if (React.isValidElement(c)) {
if (c.props.displayNameForIdentification === 'WHAT I WANT') { ... }
}
})
我不喜欢这种解决方案的事实是我自己添加了标识符,甚至道具名称displayNameForIdentification
都没有被React储存在安全的地方,但这只是一个道具:我不确定开发人员是否会覆盖该道具(好的,我只能说“从不使用displayNameForIdentification
道具”,但我想避免这种情况。)
那么,有什么方法可以识别REACT
子组件的类型?
编辑:通过遵循Ramesh的建议,我可以编写如下内容:
React.Children.forEach(props.children, (c) => {
if (React.isValidElement(c)) {
if (c.type.name === 'WHAT I WANT') { ... }
}
})
尽管,TypeScript不喜欢c.type.name
,但它给了我以下错误,而我却无法解决它:
类型'string |中不存在属性'name' ((props:any)=> ReactElement组件)>)| (new(props:any)=>组件)'。 属性“名称”在类型“字符串”上不存在。ts(2339)
对这个新来者有什么建议吗?
答案 0 :(得分:2)
使用type.name
这将返回函数的名称
import * as React from "react";
import { render } from "react-dom";
class App extends React.Component<{}> {
public render() {
return (
<div>
</div>
);
}
}
const app = <App/>
console.log(app.type.name==="App")
render(app, document.getElementById("root"));
答案 1 :(得分:0)
您可以这样做:
{children && children.every(child => child.type.displayName === "Tab")
和组件:
const Tab = (props) => {...}
Tab.displayName = "Tab"
这只是我的示例,它仅渲染名称为“ Tab”的组件