如何使用组件组合

时间:2018-04-11 16:00:05

标签: reactjs typescript

React促进组合而不是继承,但我

我在TypeScript中有一个React组件,它应该托管某些类型的React组件。例如,假设我有一个MenuBar组件,它需要一组可以作为道具托管的各种MenuBarItem组件。我想强制所有菜单栏项具有相同的根元素结构,因此它们必须在根处呈现MenuBarItem组件。

我遇到的问题是,如果我使用继承,我可以通过将prop定义为items: MenuBarItem[]之类的东西来实现这一点,但我无法弄清楚如何使用组合强制执行此操作。

通过使用合成,我创建了FooMenuBarItemBarMenuBarItem,让他们在内部呈现MenuBarItem(见下文)。因此,他们不会共享我可以用作类型的公共基类。

如何用合成解决这个打字问题?

export class MenuBarItem extends React.Component<{}, {}> {
    render() { return /*...*/; }
}
export class FooMenuBarItem extends React.Component<{}, {}> {
    render() { return <MenuBarItem>Foo</MenuBarItem>;}
}
export class BarMenuBarItem extends React.Component<{}, {}> {
    render() { return <MenuBarItem>Bar</MenuBarItem>;}
}

export interface MenuBarProps {
    items: MenuBarItem[]; // This would only work if I use inheritance to get the common base type!
}
export class MenuBar extends React.Component<MenuBarProps , {}> {
    render() {
        <div>{this.props.menuBarItems}</div>
    }
}

我发现了一个类似的问题here,但没有答案。

1 个答案:

答案 0 :(得分:1)

我认为简短的回答是没有办法宣布你想要的确切类型(否则我会有兴趣听到!)。

老实说,我通常会选择:

export interface MenuBarProps {
    items: React.ReactNode;
}

依靠代码的消费者做出明智的事情。

我要考虑的另一件事是,也许你可以使用:

export interface MenuBarProps {
    items: React.Component<MenuItemProps>;
}

只有当各种不同的菜单项组件共享一组共同的道具时,这才有意义。