如何在嵌套React函数组件中获取:root定义的CSS变量
解决方案
1. 修正CSS变量名拼写错误
你代码里的核心问题是变量名不匹配:
- CSS文件中定义的变量是
--indicator---red(indicator后有三个连字符) - 但React组件里写的是
--indicator-red(仅两个连字符)
必须保证JS中使用的变量名和CSS完全一致,否则getPropertyValue会返回空字符串。
2. 确保CSS变量文件已正确导入
确认variables.css已经在项目入口文件(如index.js/App.js)中导入:
import './variables.css';
若未导入,:root上不会挂载这些CSS变量,自然无法获取。
3. 修正后的React组件实现
使用useEffect监听状态变化,确保DOM加载完成后再获取变量,并通过trim()去除返回值的多余空格:
// TrafficLight.js import { useEffect, useState } from 'react'; function TrafficLight({ status }) { const [color, setColor] = useState(''); useEffect(() => { const rootStyles = getComputedStyle(document.documentElement); let currentColor = ''; switch (status) { case "GREEN": currentColor = rootStyles.getPropertyValue('--indicator---green').trim(); break; case "YELLOW": currentColor = rootStyles.getPropertyValue('--indicator---amber').trim(); break; case "RED": currentColor = rootStyles.getPropertyValue('--indicator---red').trim(); break; default: currentColor = ''; } setColor(currentColor); }, [status]); return <div className="circle" style={{ backgroundColor: color }} />; }
可选:封装自定义Hook复用逻辑
如果多个组件需要获取CSS变量,可以封装一个Hook简化代码:
// hooks/useCssVariable.js import { useState, useEffect } from 'react'; export function useCssVariable(variableName) { const [value, setValue] = useState(''); useEffect(() => { const updateValue = () => { const root = document.documentElement; const computedValue = getComputedStyle(root).getPropertyValue(variableName).trim(); setValue(computedValue); }; updateValue(); // 可选:监听CSS变量动态变化 const observer = new MutationObserver(updateValue); observer.observe(document.documentElement, { attributes: true, attributeFilter: ['style'] }); return () => observer.disconnect(); }, [variableName]); return value; }
在TrafficLight组件中使用:
// TrafficLight.js import { useCssVariable } from './hooks/useCssVariable'; function TrafficLight({ status }) { const colorMap = { GREEN: '--indicator---green', YELLOW: '--indicator---amber', RED: '--indicator---red' }; const color = useCssVariable(colorMap[status] || ''); return <div className="circle" style={{ backgroundColor: color }} />; }
内容的提问来源于stack exchange,提问作者Ricky Palaguachi
相关产品推荐
相关产品推荐

