使用 React 和 Redux 的主题

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)

Lak*_*kur 5

您可以利用数据属性。我在我的一个项目中也做了同样的事情,如下所示:-

[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。