您要请求功能还是报告错误?
漏洞
目前的行为是什么?
在渲染每个 item 元素上将key
设置为唯一属性的 item 列表时,如果 item 的顺序与之前的渲染相比发生了变化,则索引更改的 item 元素将重新渲染(创建新实例)而不是重新渲染- 使用现有实例(通过键映射)。
例如https://codesandbox.io/s/r5p48kzop
渲染一个列表boxes
,每个盒子都有id
、 top
、 left
和color
道具。 每750ms
我们都会更新boxes
数组中所有元素的 ( top
, left
) 值。
在更新时,如果元素的顺序没有改变,那么每个框都会动画到它的新位置。 然而,如果我们取消注释第 31 行,它会随机播放这些框,那么只有在之前渲染中保留其位置的元素才会动画到新位置。
您可以在沙箱中观察这种行为。 _shuffle
有时会跳到新位置,而_shuffle
关闭时它们总是动画。
如果当前的行为是一个错误,请提供重现的步骤,如果可能,请提供问题的最小演示。 将链接粘贴到您的 JSFiddle (https://jsfiddle.net/Luktwrdm/) 或 CodeSandbox (https://codesandbox.io/s/new) 示例如下:
https://codesandbox.io/s/r5p48kzop
什么是预期行为?
不管boxes
的顺序如何,所有框元素都应该动画到它们的新位置,因为它们具有独特的key
属性设置。
哪些版本的 React 以及哪些浏览器/操作系统受此问题影响?
反应16.3.2
和16.4.1
,Chrome,MacOS。
嘿@dhruvparmar372!
这似乎是 DOM 的限制。 为了证明这一点,我创建了这个JSFiddle ,它改变了两个 DOM 节点的顺序,然后应用一个类来触发转换。
事实证明,您可以通过在更改顺序和更新动画属性之间触发回流来解决此问题。
我在您的 CodeSandbox 中添加了一些代码,通过将<Box />
更改为类组件并在构造函数中创建唯一 id 来使其在 React 重新创建组件时可见。 如您所见,id 将保持一致: https :
除此之外,我通过将更新拆分为两个setState
将回流解决方法应用于您的示例。 第一个会改变顺序,然后我们触发回流,然后改变位置。 这似乎在 Chrome、Firefox、Safari 和 Edge 中运行良好(CodeSandbox 不支持 IE11,因此我无法在该浏览器上进行测试)。
嘿@philipp-spiess 感谢您澄清问题和解决方法的示例。
嗨,@philipp-spiess
排序列表也有同样的问题😔
不幸的是,您上面的 Codesandbox 示例不再起作用(
下面是一个例子:
https://jsfiddle.net/9odLvbrx/
它通过简单的 CSS 转换对点击项目进行排序。
问题是过渡仅出现在所选项目上,而忽略了其余项目。
我知道如何解决这个问题(在代码中注释),但它只适用于项目数量永远不会改变的列表。 所以如果我想添加或删除项目 - 这些东西变得非常复杂。 在我的示例中,我如何使用您的回流过载解决方案来实现它?
提前致谢! 😊
最有用的评论
嘿@dhruvparmar372!
这似乎是 DOM 的限制。 为了证明这一点,我创建了这个JSFiddle ,它改变了两个 DOM 节点的顺序,然后应用一个类来触发转换。
事实证明,您可以通过在更改顺序和更新动画属性之间触发回流来解决此问题。
我在您的 CodeSandbox 中添加了一些代码,通过将
<Box />
更改为类组件并在构造函数中创建唯一 id 来使其在 React 重新创建组件时可见。 如您所见,id 将保持一致: https :除此之外,我通过将更新拆分为两个
setState
将回流解决方法应用于您的示例。 第一个会改变顺序,然后我们触发回流,然后改变位置。 这似乎在 Chrome、Firefox、Safari 和 Edge 中运行良好(CodeSandbox 不支持 IE11,因此我无法在该浏览器上进行测试)。