css调用内插值函数被字符串化报错的原因与解决方案
问题成因
你触发的警告原文为:
Functions that are interpolated in css calls will be stringified.
核心原因是混淆了css工具函数和styled组件构造函数的执行逻辑:
styled.xxx/styled(Component)生成的样式组件,在渲染时会自动把组件props、ThemeProvider注入的theme作为参数,传入模板字符串里的所有插值函数,执行后拿到动态样式值- 单独调用的
css标签模板函数,没有自动注入上下文的能力,它在代码执行到定义语句的当下就会解析所有插值:如果插值位置传入的是函数,css没有能力执行这个函数拿到返回值,只会把函数本身转为字符串拼接到样式规则里,最终生成无效CSS,因此抛出警告。
你当前的写法是直接在css的插值位置写了接收theme的箭头函数,css解析时拿到的是函数类型值,既拿不到theme上下文,也无法正确生成样式,不管怎么调整这个箭头函数内部的逻辑,只要函数直接写在css插值里,就会触发这个问题。
可直接落地的解决方案
根据你的使用场景选对应写法即可:
- 场景1:该样式片段需要插值到styled组件中复用
把动态逻辑移到外层,写为接收props的函数,函数内部返回css调用结果,styled组件解析插值时会自动传入props/theme上下文:// 外层函数接收props/theme,返回css片段 const track track = ({ theme }) => css` background: rgba(theme.colors.gray['000'], 0.25); ` // 使用时直接插入styled模板即可,无需手动传参 const CustomTrack = styled.div` height: 4px; border-radius: 2px; ${track} ` - 场景2:需要在普通JS逻辑中单独拿到该样式结果(比如传给组件css属性、行内样式场景)
手动传入依赖的theme参数,执行函数拿到最终的样式对象即可:// 从hook或上下文中拿到当前主题 const theme = useTheme(); // 手动传参执行,得到可直接使用的样式 const trackStyle = track({ theme });
常见踩坑说明
不要尝试直接在css作用域内直接读取theme变量,单独的css调用不在ThemeProvider的上下文作用域内,会直接触发theme is not defined的报错,这也是很多人修改多次仍无法解决问题的核心原因。
内容的提问来源于stack exchange,提问作者SkyDev
相关产品推荐
相关产品推荐

