Javascript 我可以在React中使用组件接口吗?

Javascript 我可以在React中使用组件接口吗?,javascript,reactjs,typescript,Javascript,Reactjs,Typescript,假设我有一个,它接受和 ( 福 福 福 ) 现在,在我的Modal组件中,我可能会有如下代码: const header=children.find(child=>child.type==header) 以获取对渲染标头的引用 现在,如果从modal的消费者那里,我需要一个装饰的标题。我们就叫它DecoratedHeader //DecoratedHeader const DecoratedHeader=()=>Foo //消费者 ( 福 福 ) 上面的行将不再工作,因为Decorated

假设我有一个
,它接受

(
福
福
福
)
现在,在我的
Modal
组件中,我可能会有如下代码:

const header=children.find(child=>child.type==header)
以获取对渲染标头的引用

现在,如果从modal的消费者那里,我需要一个装饰的
标题
。我们就叫它
DecoratedHeader

//DecoratedHeader
const DecoratedHeader=()=>Foo
//消费者
(
福
福
)
上面的行将不再工作,因为
DecoratedHeader
类型是而不是
Header
。但是,它正在呈现一个
标题

感觉好像缺少了“接口”的概念。最后,
模式
关心要呈现的
标题
,但是如果将其包装在“自定义”组件下,它就无法知道它仍然是
标题

我错过了什么

编辑

为了进一步扩展我的用例,我不需要其他解决方案。我需要知道React是否支持相当于接口的机制,其中符合Liskov替换原则(意味着它们是可交换的)的两个不同组件可以由父级选择

具体而言,将此“硬编码实现”搜索替换为“接口”搜索:

-const specificChild=children.find(child=>child.type==SomeComponent)
+常量componentInterface=children.find(child=>??)
//从组件接口中获取一个道具
const{someInterfacePro}=componentInterface.props;
返回(
{componentInterface}{/*在特定位置渲染它*/}
)

假设您使用这些组件要做的唯一一件事就是在模态的特定位置渲染它们,我会将它们作为单独的道具来处理。例如:

const Modal = ({ header, content, footer }) => {
  return (
    <div>
      {header}
      <SomethingElseAllModalsHave />
      {content}
      {footer}
    </div>
  )
}

// ... used like:
const Example = () => {
  return (
    <Modal
      header={<DecoratedHeader />}
      content={<Content>Foo</Content>}
      footer={<Footer>Foo</Footer>}
    />
  )
}
然后,您将查找类似以下内容的内容(您应该使用,因为
子项
不保证是数组):


如果你想让消费者传递一个特别的
标题
,这样他们就不能传递像
手风琴这样的东西了,那该怎么办?我知道你是在用你的替代解决方案。然而,我有许多用例,我需要一个问题的答案,而不是其他方法。基本上,
child.type==组件
check我已经编辑了更多的想法。但是,我不建议你检查一下孩子们的类型和道具,然后根据它们采取行动,除非你绝对需要这样做。React的设计使得父母可以很容易地告诉孩子要渲染什么,但反过来却很棘手。根据这些信息,我将得出结论,使用
type===Component
的模式本身存在根本缺陷。谢谢你的回答,尼古拉斯!好问题。我想这可以通过将头类型ref传递给DecoratedHeader来实现,我不确定。我会自己试试
const Modal = ({ header, content, footer }) => {
  return (
    <div>
      {header}
      <SomethingElseAllModalsHave />
      {content}
      {footer}
    </div>
  )
}

// ... used like:
const Example = () => {
  return (
    <Modal
      header={<DecoratedHeader />}
      content={<Content>Foo</Content>}
      footer={<Footer>Foo</Footer>}
    />
  )
}
const Modal = ({ header, content, footer }) => {
  const [isVisible, setIsVisible] = useState(false);

  return (
    <div>
      {header(isVisible)}
      <SomethingElseAllModalsHave />
      {content(isVisible)}
      {footer(isVisible}
    </div>
  )
}

// ... used like:
const Example = () => {
  return (
    <Modal
      header={() => <DecoratedHeader />}
      content={(isVisible) => <Content>{isVisible ? "Foo" : "Bar"</Content>}
      footer={(isVisible) => isVisible ? <Footer>Foo</Footer> : null}
    />
  )
}
const Header = () => {
  // Whatever the code is for this component.
}

Header.isHeader = true;

const DecoratedHeader = () => <Header>Foo <Icon type="lock" /></Header>

DecoratedHeader.isHeader = true;
const header = React.Children.toArray(children).find(child => child.type.isHeader);