React
扩展 CSSProperties 类型后,把变量传给 style。
在线预览
运行时主题
颜色与圆角都来自组件状态。
组件关系与数据流
StateComponentDerivedStyle
差异焦点动态样式对象属于 render 结果,每次组件执行都会重新创建。
实线表示依赖、数据或命令传递,虚线表示事件、回调或清理路径。
flowchart TB
accTitle: React render 创建动态 style
accDescr: themeIndex setter 触发 ReactDemo 重新执行,每次 render 都读取 theme 并创建新的 style 对象,再通过 style prop 写入 CSS 变量。
state(["themeIndex state"]) --> render["ReactDemo 重新执行"]
render --> derive{{"每次 render 创建 style 对象"}}
derive --> variables[("CSS variables")]
variables -->|"style prop"| card["dynamic-demo-card"]
card -.->|"setThemeIndex"| state
class state state
class render,card component
class derive process
class variables resource
classDef state fill:#ffffff,stroke:#149eca,color:#172033,stroke-width:1.2px
classDef component fill:#e5f6fb,stroke:#149eca,color:#172033,stroke-width:2px,font-weight:600
classDef process fill:#f4fbfd,stroke:#149eca,color:#172033,stroke-width:1.6px
classDef resource fill:#f3f5f8,stroke:#778195,color:#172033,stroke-width:1.4pxsetter 触发组件重新执行,并在本次 render 中创建新的 style 对象。
实际运行源码
import { useState, type CSSProperties } from "react";
const themes = [ { name: "海蓝", color: "#1677ff", background: "#eaf3ff", radius: 18 }, { name: "葡萄", color: "#7c3aed", background: "#f4edff", radius: 8 },];
type CardStyle = CSSProperties & { "--demo-accent": string; "--demo-background": string; "--demo-radius": string;};
export function ReactDemo() { const [themeIndex, setThemeIndex] = useState(0); const theme = themes[themeIndex]; const style: CardStyle = { "--demo-accent": theme.color, "--demo-background": theme.background, "--demo-radius": `${theme.radius}px`, };
return ( <div className="demo-stack"> <section className="dynamic-demo-card" style={style}> <span className="demo-tag">{theme.name}</span> <h2>运行时主题</h2> <p>颜色与圆角都来自组件状态。</p> </section> <div className="demo-actions"> {themes.map((item, index) => ( <button className="demo-button" type="button" key={item.name} onClick={() => setThemeIndex(index)} > {item.name} </button> ))} </div> </div> );}