react Bug: 使用CSS变量的styles对象以及简写和特定属性都渲染不正确,

bmvo0sr5  于 5个月前  发布在  React
关注(0)|答案(8)|浏览(56)

React在使用CSS变量作为简写属性和另一个特定属性(如paddingpaddingRight)时,不会产生正确的内联样式。
样式对象:

{
  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>

重现步骤

  1. 将样式对象添加到具有属性简写和特定属性(如paddingpaddingRight)的组件中,并使用css变量(如var(--spacing))。
  2. 渲染该组件并使用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>
kh212irz

kh212irz1#

我之前报告过这个问题(#8689),但当时并没有引起太多关注。我得到的回应是,支持预期的行为会太昂贵,但也许React可以有一个DEV警告。

cwtwac6a

cwtwac6a2#

在这种情况下,如果我不使用CSS变量,似乎它可以正常工作。
这个:

{
  padding: "calc(var(--spacing) * 1)",
  paddingRight: "calc(var(--spacing) * 3)",
  paddingBottom: "calc(var(--spacing) * 4)"
};

翻译成:

<span style="padding-top: ; padding-right: calc(var(--spacing) * 3); padding-bottom: calc(var(--spacing) * 4); padding-left: ;">App</span>

但是这个:

{
  padding: "calc(10px * 1)",
  paddingRight: "calc(10px * 3)",
  paddingBottom: "calc(10px * 4)"
};

翻译成:

<span style="padding: calc(10px) calc(30px) calc(40px) calc(10px);">App</span>

尽管如此,如果支持预期行为代价太高,一个开发警告会很好(如果支持预期行为代价太高)。

jvidinwx

jvidinwx3#

我不知道ReactDOM这个特定部分的历史,所以我不确定之前有什么想法,以及除了“没有人来得及构建它”之外,当前行为(和缺乏警告)是否有任何好的理由。
不过,我也同意添加一个警告会更好。
我将为此标签进行讨论,看看其他人是否能分享更多上下文。

iqjalb3h

iqjalb3h4#

cc @syranide in case you can share any more background context.

nwnhqdif

nwnhqdif5#

嘿!我不能代表这个问题的CSS变量部分发言。但是不支持重叠样式只是简单地将性能/复杂性问题。如果React不支持重叠样式,它可以简单地迭代prev/next并将其作为属性应用任何更改,非常快速和简单。如果支持重叠样式,那么React必须知道如何分解简写属性,并能够确定更改的属性是否遮蔽/重叠另一个属性,并以正确的顺序应用它们。这显著慢得多,更复杂,而且相当脆弱。我不了解如何在不产生显著开销的情况下解决这个问题,考虑到浏览器目前暴露的功能集,这取决于人们期望从React中获得什么样的性能/使用场景,使得它变得不可接受。
由于我现在不再积极参与,所以我不能说为什么还没有警告,但我会积极认为这是因为“没有人已经着手构建它”,正如你所说的那样。这个警告应该相对简单地实现至少对于当前/常见的属性集。

oug3syen

oug3syen6#

为了说明,过去(我假设现在也是这样)设置一个简写属性的成本与单独设置它分解成的所有属性的成本相同。所以,如果你有例如 font + font-size ,改变其中一个,实际上会像 1+7 个属性更新一样,而不是仅仅 1 个,除此之外,你还需要额外的非平凡成本让 React 检查重叠。当涉及到例如 border 时,情况更糟糕,因为它需要分解成几个步骤。
可能是因为考虑到现代浏览器的状态已经得到了改善,所以与相关的渲染成本相比,这种成本可能可以忽略不计。但我最近没有进行任何测试,所以我不确定。

wz8daaqr

wz8daaqr7#

了解了RE:性能优势。更好奇的是,之前是否调查过DEV警告,并确定它也太昂贵了。

ezykj2lf

ezykj2lf8#

在过去的几个小时里,我一直在面对这个bug,最后找到了一些相关的Github讨论。我有一个系统,可以从各种来源动态添加样式,并可以展示一个流程,显示这里的问题:https://codesandbox.io/s/elated-flower-zxvkf?file=/src/App.js 。我知道性能优势可能会太昂贵,但这真是太遗憾了,因为对我来说,这似乎是一个很大的问题。
如果我最终渲染了两个带有相同样式对象的div,无论这两个div之前是否存在任何样式,我都应该期望在这两个div上得到相同的结果,我认为。

相关问题