TypeScript和React中的通用主从组件

时间:2019-07-24 21:30:57

标签: reactjs typescript

我正在尝试在TypeScript和React中创建一个通用的主从组件。父组件应负责主组件和明细组件之间的协调,即,将在主组件中选择的项目的ID传递给明细。但是,主组件和明细组件不应在父级中硬编码。这使我可以将父级MasterDetail用于不同类型的实体。总而言之,我想将主要和详细组件作为道具传递,最好是作为子项传递。

仅出于说明目的,这是我的硬编码实现(您可以在CodeSandbox上找到有效的版本):

const MasterDetail = () => {
  const [itemId, setItemId] = React.useState("");

  const handleClick = (itemId: string) => {
    setItemId(itemId);
  };

  return (
    <div className="d-flex p-2">
      <div className="lhs">
        <Master onClick={handleClick} />
      </div>
      <div className="flex-fill">
        <Detail itemId={itemId} />
      </div>
    </div>
  );
};

如您所见,MasterDetail在该组件中进行了硬编码。如何以TypeScript友好的方式将它们作为道具传递?

我通常看到使用“渲染道具”的实现,但是这种模式似乎只允许一个孩子。是否有任何模式可将其扩展到多个孩子?

1 个答案:

答案 0 :(得分:1)

如果您想使MasterDetail组件可变/动态,则使它们成为您可以传递的道具,因此它更加通用

用法将是<MasterDetail MasterComponent={Master} DetailComponent={Detail} />

现在,定义您的类型。您必须明确/确保类型匹配。

interface Props {
  DetailComponent: React.FC<DetailProps>;
  MasterComponent: React.FC<MasterProps>;
}

export const MasterDetail: React.FC<Props> = ({ DetailComponent, MasterComponent }) => {
  const [itemId, setItemId] = React.useState("");
  const handleClick = (itemId: string) => {
    setItemId(itemId);
  };

  return (
    <div className="d-flex p-2">
      <div className="lhs">
        <MasterComponent onClick={handleClick} />
      </div>
      <div className="flex-fill">
        <DetailComponent itemId={itemId} />
      </div>
    </div>
  );
};

请记住以Detail的方式定义export const Detail: React.FC<DetailProps> = ({ itemId }) => {组件的不同实例,您应该会很好