1 css themes reactjs redux react-redux
我正在尝试在一个 React 项目上制作一个主题系统,该项目使用 redux 和一个根据用户本地存储管理主题的减速器。但我的问题是我使用 css 文件来定义所有组件的样式。但是,我的所有逻辑都包含 2 个用于浅色或深色模式的 javascript 对象。所以我不能在css文件中使用js,除非我使用css变量但我不知道如何。
这是我的结构:
在我的 app.js 中,我从 React Redux 导入了 useSelector 和 useDispatch 来访问全局状态:
import React from 'react';
import './App.css';
import Footer from './components/Footer';
import Header from './components/Header';
import Presentation from './components/Presentation';
import Projects from './components/Projects';
import Skills from './components/Skills';
import Timeline from './components/Timeline';
import { switchTheme } from './redux/themeActions';
import { useSelector, useDispatch } from 'react-redux';
import { lightTheme, darkTheme } from './redux/Themes';
function App() {
const theme = useSelector(state => state.themeReducer.theme);
const dispatch = useDispatch();
return (
<div className="App">
<Header />
<input type='checkbox' checked={theme.mode === 'light' ? true : false}
onChange={
() => {
if(theme.mode === 'light') {
dispatch(switchTheme(darkTheme))
} else {
dispatch(switchTheme(lightTheme))
}
}} />
<div className="top">
<div className="leftPart">
<Presentation />
<Skills />
</div>
<Timeline />
</div>
<Projects />
<Footer />
</div>
);
}
export default App;Run Code Online (Sandbox Code Playgroud)
在 theme.js 中,我有两个代表主题的对象:
export const darkTheme = {
mode: 'dark',
PRIMARY_BACKGROUND_COLOR: '#171933',
SECONDARY_BACKGROUND_COLOR: '#1e2144',
TERTIARY_BACKGROUND_COLOR: '#0a0c29',
PRIMARY_TEXT_COLOR: '#eee',
SECONDARY_TEXT_COLOR: '#ccc',
PRIMARY_BORDER_COLOR: '#aaa'
}
export const lightTheme = {
mode: 'light',
PRIMARY_BACKGROUND_COLOR: '#D3CEC8',
SECONDARY_BACKGROUND_COLOR: '#E5DFD9',
TERTIARY_BACKGROUND_COLOR: '#C1BFBC',
PRIMARY_TEXT_COLOR: '#222',
SECONDARY_TEXT_COLOR: '#333',
PRIMARY_BORDER_COLOR: '#555'
}Run Code Online (Sandbox Code Playgroud)
您可以利用数据属性。我在我的一个项目中也做了同样的事情,如下所示:-
[data-color-mode="light"] {
--color-focus-ring: #7daee2;
--color-link-hover: #0039bd;
--color-primary-bg: #eef6ff;
--color-primary-text: #212121;
--color-primary-border: #98b2c9;
--color-secondary-bg: #c3d7f0;
--color-secondary-text: #1a1a1a;
}
[data-color-mode="dark"] {
--color-focus-ring: #5355d4;
--color-link-hover: #4183c4;
--color-primary-bg: #080808;
--color-primary-text: #f1f1f1;
--color-primary-border: #525252;
--color-secondary-bg: #191919;
--color-secondary-text: #d8d5d5;
}
Run Code Online (Sandbox Code Playgroud)
您可以将该属性添加到顶级元素(假设为 div),如下所示:-
<div className="appContainer" data-color-mode="light" ref={appRef}> ></div>
现在使用它appRef来更改data-color-mode属性并在一个函数中更新本地存储。更新data-color-mode允许您轻松地在 css 变量颜色之间切换。在我的代码中,我按照以下方式完成了此操作:-
const toggleColorMode = () => {
const nextMode = mode === "light" ? "dark" : "light";
// container is appRef.current only
container?.setAttribute("data-color-mode", nextMode);
setMode(nextMode);
};
Run Code Online (Sandbox Code Playgroud)
我没有为此使用 redux。我正在使用 Simply React Context API,但它在您的场景中也是可行的。
您可以从存储库中获取更多参考 - https://github.com/lapstjup/animeccha/tree/main/src
注意 - 我认为人们还有其他途径使用 CSS-IN-JS,但我还没有探索过它们。这个解决方案是纯css方式之一。
有趣的事实 - Github 以类似的方式实现了他们最新的黑暗模式,这也是我的想法的来源。您可以检查他们的页面以查看相同的属性名称:D。