Material-UI Button 组件如何推断传递给 `component` 属性的组件的属性?

Posted

技术标签:

【中文标题】Material-UI Button 组件如何推断传递给 `component` 属性的组件的属性?【英文标题】:How does Material-UI Button component infer the props for the component passed to `component` prop? 【发布时间】:2021-11-27 15:20:38 【问题描述】:

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

interface MyLinkProps extends ButtonBaseProps 
  someRandomProp: string


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


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

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

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

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

<MyImage component=NextImage ...propsOfNextImage />

基本上,我希望MyImage 自动检测和扩展NextImage 的道具。

【问题讨论】:

【参考方案1】:

可以看到OverridableComponenthere的类型定义,这个负责将overridable component的props与组件原有的props合并。

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

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>

现场演示

【讨论】:

以上是关于Material-UI Button 组件如何推断传递给 `component` 属性的组件的属性?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Typescript 扩展 Material-UI 组件的道具?

如何在 Material-UI 中使用 Box 组件覆盖按钮?

如何禁用样式组件内material-ui按钮的悬停效果

如何使用 styled-components 将 prop 传递给 Material-UI 组件

ESLint: '@material-ui/core/Button' 导入被限制使用

打字稿:React.forwardRef 带有来自@material-ui 的通用道具