我正在创建一个自定义组件,该组件扩展了Material-UI的Typography
组件。
该组件用于我正在创建的模板,因此我想包括覆盖默认类的选项。一个非常基本的指南是provided by Material-UI here,但是当您不能简单地将所有道具传递给useStyles(props)
时,它没有提供有关如何执行此操作的详细信息。
我不能将所有props
传递给useStyles(props)
如下:
Typography
组件,因此一些道具被解构(供新的自定义组件使用),而所有其他道具都使用散布运算符传递给Typography
组件。useStyles(props)
。如果我将所有道具传递给useStyles(props)
,则这会导致上述第2点出现问题,因为我无法解构这些仅用于样式的道具,因此它们会作为散布运算符的一部分传递到Typography
组件中。下面是一些说明问题的代码:
// useStyles()
const useStyles = makeStyles(theme => ({
/** Styles applied to the root element */
root: (props: StylesProps) => ({
color: theme.palette.primary.main,
fontFamily: props.fontFamily,
fontWeight: props.weight,
letterSpacing: props.letterSpacing,
lineHeight: 1,
textTransform: props.casing
}),
/** Styles applied to the second logo text if `name[1] !== undefined` */
nameEnd: {
color: theme.palette.secondary.main
},
/** Styles applied to the root element if `textShadow=true` */
textShadow: {
textShadow: theme.textShadow
}
}));
// Component
const Logo = React.forwardRef(function Logo(props: LogoProps, ref) {
const {
casing = "uppercase", // HAS ISSUES 1, 2 and 3
className,
fontFamily, // HAS ISSUES 2 and 3
letterSpacing, // HAS ISSUES 2 and 3
name,
nameSpacing = false,
textShadow = true, // HAS ISSUES 1, 2 an 3
weight, // HAS ISSUES 2 and 3
...other
} = props;
const stylesProps: StylesProps = {
casing,
fontFamily,
letterSpacing,
weight
};
const tiqClasses = useStyles(stylesProps);
const [nameStart, nameEnd] = name;
function LogoText(): JSX.Element {
return (
<React.Fragment>
{nameStart}
{nameSpacing && " "}
{nameEnd && <span className={tiqClasses.nameEnd}>{nameEnd}</span>}
</React.Fragment>
);
}
return (
<Typography
className={clsx(className, tiqClasses.root, {
[tiqClasses.nameEnd]: nameEnd,
[tiqClasses.textShadow]: textShadow
})}
component="p"
ref={ref}
{...other}
>
<LogoText />
</Typography>
);
});
如果我将代码更改为:
// Component
const Logo = React.forwardRef(function Logo(props: LogoProps, ref) {
const {
className,
name,
nameSpacing = false,
...other
} = props;
const tiqClasses = useStyles(props);
const [nameStart, nameEnd] = name;
function LogoText(): JSX.Element {
return (
<React.Fragment>
{nameStart}
{nameSpacing && " "}
{nameEnd && <span className={tiqClasses.nameEnd}>{nameEnd}</span>}
</React.Fragment>
);
}
return (
<Typography
className={clsx(className, tiqClasses.root, {
[tiqClasses.nameEnd]: nameEnd,
[tiqClasses.textShadow]: textShadow
})}
component="p"
ref={ref}
{...other}
>
<LogoText />
</Typography>
);
});
这意味着:
casing
和textShadow
道具不再具有默认值casing
,fontFamily
,letterSpacing
和weight
都被传递到Typography
传播运算符下的...other
组件,因为它们是不再被破坏。这些不是Typography
组件的有效道具,因此它们作为DOM属性被传递下来,由于它们也不是有效的DOM属性,因此也会导致错误。我要实现的目标
我希望能够通过使用如下组件来覆盖root
,nameEnd
和textShadow
类:
<Logo tiqClasses={{ root: "rootOverwriteClass", nameEnd: "nameEndOverwriteClass" }} classes={{ body1: "body1OverwriteClass" }} {...otherProps} />
与makeStyles
相比,我更愿意withStyles
使用tiqClasses
。
注意:为了澄清,我使用的是classes
而不是classes
,因为{{1}}已被Material-UI使用。您可以在上面的示例中看到这一点,其中我为每个名称使用了不同的名称。
我该如何实现?