使用Emotion Styled组件传递布尔Props时的React警告问题咨询
我在渲染一个Emotion styled组件时遇到了React警告,以下是具体场景和问题:
初始代码与警告
定义的组件如下:
const FilterIcon = styled(TbFilter)<{ applied: boolean }>(({applied}) => ({ color: applied ? 'transparent' : colors.blue[500], fill: applied ? fillLinearGradient(colors.blue[300], colors.blue[500]) : undefined, }))
使用方式:
return ( <> <IconButton> <FilterIcon fontSize={ICON_SIZE} applied={applied} /> </IconButton> {childrens} </> )
其中applied是默认值为false的布尔值,React抛出警告:
Warning: Received
falsefor a non-boolean attributeapplied.If you want to write it to the DOM, pass a string instead: applied="false" or applied={value.toString()}.
If you used to conditionally omit it with applied={condition && value}, pass applied={condition ? value : undefined} instead.
我想知道Emotion是否支持非字符串props?
修改后的代码与新警告
尝试将prop改为$applied:
const FilterIcon = styled(TbFilter)<{ $applied: boolean }>` color: ${(props) => props.$applied ? 'transparent' : colors.blue[500]}; fill: ${(props) => props.$applied ? fillLinearGradient(colors.blue[300], colors.blue[500]) : undefined}; ` return ( <> <IconButton> <FilterIcon fontSize={ICON_SIZE} $applied={applied}/> </IconButton> {childrens} </> )
又出现新警告:
Warning: Invalid attribute name:
$applied
问题解答
Emotion完全支持非字符串props,问题根源在于:React会把styled组件接收的所有未被明确过滤的props,传递给底层的DOM元素或基础组件(这里是TbFilter)。而DOM元素不认识applied或$applied这类自定义属性,因此抛出警告。
解决方法
使用Emotion的shouldForwardProp配置,指定哪些props不需要传递给底层组件/DOM:
函数式styled写法的修正
const FilterIcon = styled(TbFilter, { // 只转发除了'applied'之外的props给TbFilter shouldForwardProp: (prop) => prop !== 'applied' })<{ applied: boolean }>(({applied}) => ({ color: applied ? 'transparent' : colors.blue[500], fill: applied ? fillLinearGradient(colors.blue[300], colors.blue[500]) : undefined, }))
模板字符串写法的修正
如果用模板字符串写法,同样可以添加shouldForwardProp:
const FilterIcon = styled(TbFilter, { shouldForwardProp: (prop) => prop !== '$applied' })<{ $applied: boolean }>` color: ${(props) => props.$applied ? 'transparent' : colors.blue[500]}; fill: ${(props) => props.$applied ? fillLinearGradient(colors.blue[300], colors.blue[500]) : undefined}; `
原理是:shouldForwardProp告诉Emotion哪些props仅用于样式计算,不需要传递给底层的DOM元素或组件,这样React就不会把这些自定义props当作DOM属性处理,也就不会抛出警告了。
内容的提问来源于stack exchange,提问作者Antonio Santoro

