React在使用CSS变量作为简写属性和另一个特定属性(如padding
和paddingRight
)时,不会产生正确的内联样式。
样式对象:
{
padding: "calc(var(--spacing) * 1)",
paddingRight: "calc(var(--spacing) * 3)",
paddingBottom: "calc(var(--spacing) * 4)"
};
产生以下样式:
而以下HTML:
<span style="padding-top: ; padding-right: calc(var(--spacing) * 3); padding-bottom: calc(var(--spacing) * 4); padding-left: ;">App</span>
尽管在开发工具的计算属性选项卡中似乎正确,并且在屏幕上正确渲染了padding:
如果我删除css变量,一切都按预期工作。
React版本:从v15.0.0到16.12.0
- 注意*:低于v15.0.0的样式是正确生成的:
<span style="padding:calc(var(--spacing) * 1);padding-right:calc(var(--spacing) * 3);padding-bottom:calc(var(--spacing) * 4);">App</span>
重现步骤
- 将样式对象添加到具有属性简写和特定属性(如
padding
和paddingRight
)的组件中,并使用css变量(如var(--spacing)
)。 - 渲染该组件并使用dev-tools进行检查。
链接到代码示例: https://codesandbox.io/s/heuristic-wood-bjr1y
样式对象:
{
padding: "calc(var(--spacing) * 1)",
paddingRight: "calc(var(--spacing) * 3)",
paddingBottom: "calc(var(--spacing) * 4)"
};
当前行为
当使用CSS变量作为简写属性和另一个特定属性时,React不会产生正确的内联样式:
<span style="padding-top: ; padding-right: calc(var(--spacing) * 3); padding-bottom: calc(var(--spacing) * 4); padding-left: ;">App</span>
预期行为
使用CSS变量的内联样式应该产生正确的样式。
<span style="padding: calc(var(--spacing) * 1); padding-right: calc(var(--spacing) * 3); padding-bottom: calc(var(--spacing) * 4);">App</span>
8条答案
按热度按时间kh212irz1#
我之前报告过这个问题(#8689),但当时并没有引起太多关注。我得到的回应是,支持预期的行为会太昂贵,但也许React可以有一个DEV警告。
cwtwac6a2#
在这种情况下,如果我不使用CSS变量,似乎它可以正常工作。
这个:
翻译成:
但是这个:
翻译成:
尽管如此,如果支持预期行为代价太高,一个开发警告会很好(如果支持预期行为代价太高)。
jvidinwx3#
我不知道ReactDOM这个特定部分的历史,所以我不确定之前有什么想法,以及除了“没有人来得及构建它”之外,当前行为(和缺乏警告)是否有任何好的理由。
不过,我也同意添加一个警告会更好。
我将为此标签进行讨论,看看其他人是否能分享更多上下文。
iqjalb3h4#
cc @syranide in case you can share any more background context.
nwnhqdif5#
嘿!我不能代表这个问题的CSS变量部分发言。但是不支持重叠样式只是简单地将性能/复杂性问题。如果React不支持重叠样式,它可以简单地迭代prev/next并将其作为属性应用任何更改,非常快速和简单。如果支持重叠样式,那么React必须知道如何分解简写属性,并能够确定更改的属性是否遮蔽/重叠另一个属性,并以正确的顺序应用它们。这显著慢得多,更复杂,而且相当脆弱。我不了解如何在不产生显著开销的情况下解决这个问题,考虑到浏览器目前暴露的功能集,这取决于人们期望从React中获得什么样的性能/使用场景,使得它变得不可接受。
由于我现在不再积极参与,所以我不能说为什么还没有警告,但我会积极认为这是因为“没有人已经着手构建它”,正如你所说的那样。这个警告应该相对简单地实现至少对于当前/常见的属性集。
oug3syen6#
为了说明,过去(我假设现在也是这样)设置一个简写属性的成本与单独设置它分解成的所有属性的成本相同。所以,如果你有例如
font
+font-size
,改变其中一个,实际上会像 1+7 个属性更新一样,而不是仅仅 1 个,除此之外,你还需要额外的非平凡成本让 React 检查重叠。当涉及到例如border
时,情况更糟糕,因为它需要分解成几个步骤。可能是因为考虑到现代浏览器的状态已经得到了改善,所以与相关的渲染成本相比,这种成本可能可以忽略不计。但我最近没有进行任何测试,所以我不确定。
wz8daaqr7#
了解了RE:性能优势。更好奇的是,之前是否调查过DEV警告,并确定它也太昂贵了。
ezykj2lf8#
在过去的几个小时里,我一直在面对这个bug,最后找到了一些相关的Github讨论。我有一个系统,可以从各种来源动态添加样式,并可以展示一个流程,显示这里的问题:https://codesandbox.io/s/elated-flower-zxvkf?file=/src/App.js 。我知道性能优势可能会太昂贵,但这真是太遗憾了,因为对我来说,这似乎是一个很大的问题。
如果我最终渲染了两个带有相同样式对象的div,无论这两个div之前是否存在任何样式,我都应该期望在这两个div上得到相同的结果,我认为。