[英]reactjs&mui - how to properly share styles?
我想在我的整个 web 应用程序之间共享样式。
我的问题:我目前正在使用makeStyles
如下所示:
组件_A.js
const useStyles = makeStyles({
specific_style: {
padding: '24px',
// etc.
}
})
function foo() {
const classes = useStyles();
return (
<div className={classes.specific_style}>This is a styled div</div>
)
}
组件_B.js
const useStyles = makeStyles({
specific_style: {
padding: '24px',
// etc.
}
})
function bar() {
const classes = useStyles();
return (
<div className={classes.specific_style}>This is another styled div</div>
)
}
因此,我目前有很多重复的代码。 我想过把这些类放到一个主题中并像{theme.specific_style}
一样访问它,这可能吗? 我试过了,但到目前为止没有成功。
有人可以与我和后面的人分享一个工作示例吗? :)
我想到的可能解决方案:
.js
然后导入它,但感觉也不对,因为我已经访问了主题 - 我想这就是这些样式应该存在的地方。将主题与makeStyles()
是在整个文件系统中共享样式的一种方式。 makeStyles()
函数除了接受一个对象之外,还可以接受一个函数:
const useStyles = makeStyles((theme) => {
root: {
minWidth: '100%',
color: theme.textColor,
}
}
通过这种方式,您可以在样式对象中使用更高级别的主题组件。 您需要做的是创建一些主题文件,在其中保留所有共享样式,然后以与导入组件相同的方式导入该对象。
import { lightTheme } from './theme';
其他选项包括使用主题提供程序: https : //material-ui.com/styles/advanced/
您也可以将主题传递给道具。
TL;DR:根据您的讨论,您希望在将样式传递给主题提供程序之前制作样式:
const useStyles = makeStyles({specific_style: {spacing: 8}, /*more */});
function UseTheme() {
const classes = useStyles();
return (<ThemeProvider theme={classes}><DeepChild /></ThemeProvider>);
}
function DeepChild() {
const theme = useTheme();
return <span className={theme.specific_style}>specific_style spacing</span>;
}
否则,您传递的是原始对象而不是 CSS 类名。 在这个pastebin 中尝试你的风格。
NL;PR:现在,就样式共享原理而言,由于主题提供者在内部是上下文提供者,因此会降低组件的可重用性。
有四种样式范围:
const useStyles = makeStyles(
{'@global': {'.aGlobalStyleClass': {spacing:8} /*more */}
);
function UseTheme() {
const classes = useStyles();
return (<div className="aGlobalStyleClass">);
}
//from MUI's page
const theme = createMuiTheme({
components: {
// Style sheet name ⚛️
MuiButton: {
styleOverrides: {
// Name of the rule
textPrimary: {
// Some CSS
color: 'white',
},
},
},
},
});
Contextual Style 组件覆盖:这是您一直在讨论的一个,您可以在其中决定是否覆盖组件初始样式,但是,该组件需要是主题提供者的使用者。 “谨慎应用”,也许将 useStyles() 移动到组件的公共父级是更好的解决方案。 主要示例使用它。
本地样式组件覆盖:您的公共类名={classes.style} 或 style={}。 如前所述,调用 useStyles() 的地方有很大的不同。 通过在组件层次结构中向上移动样式创建来减少样式重复。
const useStyles = makeStyles({specific_style: {spacing: 8}, /*more */});
function Parent() {
const classes = useStyles();
return (<><Child1 classes={classes}/><Child2 classes={classes}/></>);
}
function Child1({classes}) {
return <span className={classes.specific_style}>specific_style spacing</span>;
function Child2({classes}) {
return <div className={classes.specific_style}>specific_style spacing</div>;
}
我假设您在上下文和本地样式覆盖之间左右为难。 两者都需要,但我将通过沿组合层次结构扩展样式来消除任何重复的样式,因为主题提供程序的更改将影响其所有组件子树。
如果您计划创建自定义实用程序类并在任何地方使用它们,您可以使用类名将它们添加到组件中的主题覆盖和访问中。
将覆盖添加到 mui 主题
let theme = createMuiTheme({
overrides: {
MuiAppBar: {
root: {
transform: 'translateZ(0)'
}
}
},
props: {
MuiIconButton: {
disableRipple: true
}
}
});
theme = responsiveFontSizes(theme);
theme.overrides.MuiCssBaseline = {
'@global': {
'.testMe': {
color: 'red'
},
'.container-std': {
[theme.breakpoints.up('lg')]: {
maxWidth: '1200px',
marginLeft: 'auto',
marginRight: 'auto'
}
},
'.container-wide': {
margin: theme.spacing(2, 2)
}
}
};
注入您的布局
import { theme } from './styles';
import Footer from '../footer/Footer';
export default function Layout(props) {
const { children } = props;
return (
<ThemeProvider theme={theme}>
<CssBaseline />
<Grid container direction="column">
<Grid item style={{ height: '70px' }}>
<Header />
</Grid>
<Grid item>
<div>
{children}
</div>
</Grid>
<Grid item>
<Footer />
</Grid>
</Grid>
</ThemeProvider>
);
}
在你的组件中使用它们
export default function HomePage() {
const classes = useStyles();
return (
<Box className={`${classes.hero} container-wide`}>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.