基于状态切换CSS变量实现React应用SVG主题色切换
解决方案
1. 将状态从硬编码颜色改为状态标识
修改topbar.js中的phoneState状态,不再存储具体颜色值,而是存储连接状态的标识(active/inactive),让颜色完全由CSS变量控制:
import React from "react"; import { useState, useEffect } from "react"; import "./topbar.scss"; import "../components/themes.scss" const electron = window.require('electron'); const { ipcRenderer } = electron; const TopBar = () => { const Store = window.require('electron-store'); const store = new Store(); // 存储状态标识而非颜色值 const [phoneState, setPhoneState] = useState("inactive"); const [theme, setTheme] = useState(store.get("colorTheme")); const plugged = () => { setPhoneState("active"); } const unplugged = () => { setPhoneState("inactive"); } useEffect(() => { ipcRenderer.send('statusReq'); ipcRenderer.on("plugged", plugged); ipcRenderer.on("unplugged", unplugged); return function cleanup() { ipcRenderer.removeListener('plugged', plugged); ipcRenderer.removeListener('unplugged', unplugged); }; }, []); return ( <div className="topbar" data-theme={theme}> <div className="topbar__info"> {/* 根据状态添加对应类名 */} <svg className={`topbar__icon topbar__icon--${phoneState}`}> <use xlinkHref="./svg/phone.svg#phone"></use> </svg> </div> </div> ); }; export default TopBar;
2. 在SCSS中关联状态类与CSS变量
修改TopBar.scss,给不同状态的SVG图标绑定对应的CSS变量,自动适配当前主题颜色:
.topbar { display: flex; flex-direction: row; justify-content: space-between; position: absolute; top: 0; height: 66px; width: 100%; background: #000000; &__info { margin-left: 3rem; } &__icon { margin-top: 1rem; margin-right:1rem; width: 1rem; height: 1rem; // 未连接状态使用主题的inactive变量 &--inactive { fill: var(--fillInactive); } // 连接状态使用主题的active变量 &--active { fill: var(--fillActive); } } }
3. 确保SVG内部元素继承外部样式
检查phone.svg文件,确保内部图形元素(如<path>)没有硬编码fill值,或设置为fill="inherit"/fill="currentColor",让外部样式能生效:
<svg id="phone" viewBox="0 0 24 24"> <path fill="inherit" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 17h-2v-2h2v2zm2.07-7.75l-.9.92C13.45 12.9 13 13.5 13 15h-2v-.5c0-1.1.45-2.1 1.17-2.83l1.24-1.26c.37-.36.59-.86.59-1.41 0-1.1-.9-2-2-2s-2 .9-2 2H8c0-2.21 1.79-4 4-4s4 1.79 4 4c0 .88-.36 1.68-.93 2.25z"/> </svg>
核心逻辑说明
- 彻底移除JavaScript中的硬编码颜色,所有颜色逻辑由CSS变量接管,与主题系统完全兼容
- React状态仅管理业务逻辑(连接状态),样式逻辑完全隔离在CSS中,符合关注点分离原则
- 通过类名切换自动匹配当前
data-theme对应的颜色值,无需手动同步主题与状态颜色
内容的提问来源于stack exchange,提问作者Traxan
相关产品推荐
相关产品推荐

