我正在使用styled-components
处理React应用中的样式。
使用ThemeProvider
包装器,我可以访问所有样式化组件中的主题
但是,我想知道是否有可能仅覆盖主题的一部分。
这是一个简单的例子:
假设我有以下主题:
const theme = {
color: 'red';
backgroundColor: 'blue';
}
我将其传递给我的应用程序
<ThemeProvider theme={theme}>
<MyStyledComponent>
<p>Hi</p>
<MyStyledComponent>
</ThemeProvider>
MyStyledComponent是一个样式化的div,用于接收我的主题:
import styled, { css } from 'styled-components'
const StyledButton = styled.button`
${props => ({
color: props.theme.color,
background-color: props.theme.backgroundColor,
})}
`
export default StyledButton
如果显示此内容,则会有一个蓝色的div,其中有一些红色的文字。
现在,如果我使用以下内容:
<ThemeProvider theme={theme}>
<MyStyledComponent theme={{color: 'green',}}>
<p>Hi</p>
<MyStyledComponent>
</ThemeProvider>
我的文本将变为绿色,但不再是蓝色背景色。
是否有一种通用方法可以确保自定义主题仅覆盖两个主题对象中都存在的属性?
答案 0 :(得分:1)
theme
使用的MyStyledComponent
实际上完全被最接近的ThemeProvider
所定义。
先前的解决方案效果很好,但是例如为了避免在{{...theme.color, color: 'green'}}
处重复,可以创建一个小的包装器:
const WithMainTheme = ({ theme: localTheme, children, ...props }) => {
return (
<ThemeProvider theme={{ ...theme, ...localTheme }}>
{React.cloneElement(children, props)}
</ThemeProvider>
);
};
这将允许您编写:
<WithMainTheme theme={{ color: "green" }}>
<MyStyledComponent>Hi</MyStyledComponent>
</WithMainTheme>
使用color: green
有关运行示例,请参见this
答案 1 :(得分:0)
您可以使用扩展运算符像JS中的普通Object一样,最后覆盖您想要的对象。
<ThemeProvider theme={theme}>
<MyStyledComponent theme={{...theme,color: 'green'}}>
<p>Hi</p>
<MyStyledComponent>
</ThemeProvider>