可行但需避免在 styled 中调用 Hook,因 styled 执行时组件未挂载;state 应在组件内计算后通过 props 传入,复杂逻辑用 useMemo 提前收口,样式片段用数组合并,引用需稳定缓存。
直接用组件 state 控制 CSS-in-JS 样式是可行的,但必须绕过「在 styled 函数里调用 Hook」这个致命错误——styled 执行时组件还没挂载,useState 或 useTheme 会立刻报 Invalid hook call。
因为 styled.button 是一个工厂函数,它只运行一次(模块初始化时),返回的是一个 React 组件类型,不是渲染函数。你写的 ${props => props.color} 中的 props 来自组件调用时传入,不是来自 useState 的返回值。
const Button = styled.button`${() => { const [c] = useState('red'); return `color: ${c}`; }}` → 报错所谓“复杂”,往往指多条件组合(如 size + variant + isDisabled + theme.mode)、带单位计算(rem 转换)、或依赖外部状态(如全局 loading 状态)。这类逻辑绝不塞进样式函数体。
const btnClass = useMemo(() => getButtonClass({ size, variant, isDisabled, theme }), [size, variant, isDisabled, theme])
margin: ${spacingMap[props.spacing]}px,而不是 margin: ${props.spacing}rem(rem 需要根字体尺寸,易出错)单个 styled 组件支持同时消费多个样式来源,但拼接方式影响可维护性与性能。
立即学习“前端免费学习笔记(深入)”;
const Comp = styled.div(props => [baseStyle, props.isActive && activeStyle, props.theme.dark && darkModeStyle]) —— css 返回的是对象或模板字符串,数组会被 emotion/styled-components 合并为一个 classcss({ '&:hover': { color: 'red' } }) 比 css`&:hover { color: red; }` 多一层解析,简单交互场景没必要css 常量,别重复写三遍真正容易被忽略的点是引用稳定性:哪怕你把 state 提前算好了,如果每次渲染都传一个新对象({ config: { size: 'lg' } }),CSS-in-JS 库的浅比较就会失效,导致无谓的样式重建。用 useMemo 缓存 props 对象,或改用扁平字段(size="lg")更稳妥。