我正在研究一个项目,该项目将动态允许用户更改主题,并在后台使用reactstrap和样式化组件。我们想通过SASS配置所有变量,效果很好。为了使这些变量可用于样式组件,我们一直在使用sass-extract-loader创建主题对象。
当我们静态选择一个主题时,所有这些都很好用,但我无法使其可靠地动态工作。我有两个问题:
1)在开发中,一次切换主题 效果很好。如果我再次更改它,则我的非样式化组件(即原始reactstrap组件)将使用第二个主题进行样式设置。我相信这是因为第二个主题是加载和覆盖原始CSS。 2)在生产中,默认情况下,我得到的混合效果与#1相同(即,因为所有CSS文件都被放到一个单独的包中,因此reactstrap组件以一种方式设置样式,而有样式的组件则“赞扬”主题)
我认为对我们来说最好的选择是将主题放在两个单独的CSS文件中,并在它们之间切换“替代”关联。我只是不知道如何配置CRA而不是将所有CSS都放在一个主包中,而是让我手动添加指向替代样式表的链接。如果我可以将它们拆分成单独的文件,我相信我可以添加标签并动态交换rel =“ alternate”属性。
可能会有更好的方法来完成此任务。我的理解是控制Bootstrap主题的最简单方法是通过SASS变量,并且我想确保在样式组件中使用它们时不必重新定义这些变量。
答案 0 :(得分:0)
如果要有条件地应用样式,则可以将样式表导入index.js文件,并通过上下文API将其提供给所有组件。首先,我们将CSS文件导入index.js
。
import themeA from './css/themeA.css';
import themeB from './css/themeB.css';
但是,通过这种方式使用, 您不能在两个CSS文件中都有元素选择器 ,因为它们将从两个文件中全局应用。但是,您可以导入一个补充所选主题的额外样式表,在其中定义元素选择器。
通过使用CSS模块,您无需元素选择器。如果您不熟悉CSS模块,则可能需要阅读本文:https://javascriptplayground.com/css-modules-webpack-react/
如果仍然需要在一个主题中应用元素选择器,可以这样做,但是它们也会以这种方式应用于您的另一主题中。
import './css/default.css';
下面的示例是React文档的修改版本:https://reactjs.org/docs/context.html
在此示例中,我们绘制了一个按钮,当 它的点击。此示例中的三个部分至关重要 了解您是否要使用React的上下文API。
1。创建上下文。
通过将React.createContext(yourValue)
的返回值分配给变量来完成创建上下文。然后可以使用此变量在React组件中使用Provider或Consumer组件。
const ThemeContext = React.createContext();
2。通过将其作为道具传递给您的Provider组件来提供值。现在,您的所有组件都可以访问该值。
class App extends React.Component {
swapTheme() {
this.setState({ withThemeA: !this.state.withThemeA });
}
render() {
const theme = this.state.withThemeA ? themeA : themeB;
return (
<ThemeContext.Provider value={theme}>
<ThemedButton onClick={this.swapTheme} />
</ThemeContext.Provider>
);
}
}
3。收听使用Consumer组件的更新。 要监听更改,您需要使用Consumer组件。传递的函数接收主题作为参数,因此可以将其分配给按钮元素的className属性。
class ThemedButton extends React.Component {
render() {
return <ThemeContext.Consumer>
{theme => <button className={theme.Button}}>click me</button>}
</ThemeContext.Consumer>;
}
}