React Hook-识别“ typeof”子组件

时间:2019-12-05 11:36:49

标签: javascript reactjs typescript

我正在构建一个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.displayNamethis.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)

对这个新来者有什么建议吗?

2 个答案:

答案 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”的组件