首页 > 解决方案 > Material-UI Button 组件如何推断传递给 `component` 属性的组件的属性?

问题描述

Button如果我在道具中传递特定组件,任何人都可以解释 Material-UI 如何使用我的组件的道具扩展其组件的component道具吗?

interface MyLinkProps extends ButtonBaseProps {
  someRandomProp: string
}

const MyLink: React.FC<MyLinkProps> = () => {
  return <div></div>
}

<Button component={MyLink} someRandomProp="random">Something</Button>

在这种情况下,Button组件现在知道someRandomProp属于我的组件的道具;它被传递给组件component上的 prop 。Button

我想达到同样的效果。我有一个 Image 组件,它有一个道具component,我想推断正在传递的组件的道具。

例如,如果有类似的东西:

<MyImage component={NextImage} {...propsOfNextImage} />

基本上,我想MyImage自动检测和扩展NextImage.

标签: reactjstypescriptmaterial-uinext.js

解决方案


可以看到OverridableComponent 这里的类型定义,这个负责将可覆盖组件的 props 与组件原有的 props 进行合并

作为参考,请在此处查看它在 MUI 组件中的使用方式。第一个泛型类型参数是具有以下属性的类型:

  • props:在与可覆盖组件的 props 合并之前,组件的原始 props。
  • defaultComponent:如果您不提供任何根组件,则为默认根组件。
import { OverridableComponent } from '@mui/material/OverridableComponent';

interface MyImageProps {
  src: string;
  myCustomProps?: string;
}
interface MyImageTypeMap {
  props: MyImageProps;
  defaultComponent: 'img';
}

const MyImage: OverridableComponent<MyImageTypeMap> = (props) => {
  const RootComponent = props.component || 'img';
  return (
    <RootComponent src={props.src} {...props}>
      {props.children}
    </RootComponent>
  );
};

用法

{/* normal component with MyImageProps. The root component is an img element */}
<MyImage src={src} />
{/* component with MyImageProps & ButtonProps. The root component is a Button*/}
<MyImage src={src} component={Button} variant="contained">
  I am actually a button in disguise
</MyImage>

现场演示

Codesandbox 演示


推荐阅读