为什么React的DOM对帐无法按预期进行?

帕维尔·波莫兰采夫(Pavel Pomerantsev)

我正在尝试使用React交换一个元素的两个孩子。

<div style={{position: 'relative'}}>
  {this.state.items.map((item, index) => (
    <div
        key={item}
        style={{position: 'absolute',
                transform: `translateY(${index * 20}px)`,
                transition: '1s linear transform'}}>
      {item}
    </div>
  ))}
</div>

state.items是两个项目的数组。重新排序时,两个孩子div应该过渡到新的位置。

现实情况是,当第二个元素按预期过渡时,第一个元素立即跳了起来。

据我所知,React认为它可以重用一个子元素,但不能重用其他子元素,尽管文档说如果我们使用该key属性,它应该始终重用元素:https : //facebook.github.io /react/docs/reconciliation.html(至少,我是这样理解的)。

我应该在代码中进行哪些更改以使其按预期工作?还是React中的错误?

实时示例:http//codepen.io/pavelp/pen/jAkoAG

z

警告:我在这个答案中做一些假设,尽管如此,它仍然可以反映出您(以前是我的)一些问题。同样,我的解决方案几乎可以肯定得到简化,但是出于回答这个问题的目的,它应该足够了。


这是一个很好的问题。打开开发工具并查看交换项目时实际发生的事情,我感到有些惊讶。

如果你看一看,你可以有点明白作出反应达到。第二个元素根本不更改其样式属性,仅交换内部文本节点,而第一个元素作为新元素放入dom中。

如果我不得不猜测的话,这是因为交换数组中的两个项目的工作方式是,其中至少有一个项目被复制到temp变量中,然后又放回到数组中。

我以为,如果您随机进行翻译,则两个元素都会获得新的风格道具和动画效果,但这只是更清楚地表明了这不是预期的行为。

在寻找解决方案的途中

作为实验,如果我们提前创建节点,然后将索引prop传递到render中,该怎么办React.cloneElement在此过程中,让我们呈现一个spanifindex === 0divelse。无需担心任何按键。

http://codepen.io/alex-wilmer/pen/pbaXzQ?editors=1010

现在打开开发工具可以准确地说明React的意图。React正在保留元素,仅更改相关部分,在这种情况下,是innerText节点和元素类型。因为样式正好按1:1交换,所以不需要样式更新。

解决方案:

您可以提前生成React元素,将其保留在数组中,这样就没有键可以改组并弄清楚如何放回DOM中。然后使用另一个数组来跟踪预期的顺序。可能极度令人费解,但它可行!

http://codepen.io/alex-wilmer/pen/kXZKoN?editors=1010

const Item = function (props) {
  return (
    <div
      style={{position: 'absolute',
        transform: `translateY(${props.index * 20}px)`,
        transition: '0.5s linear transform'}}>
      {props.children}
    </div>
  )
}

const App = React.createClass({
  getInitialState () {
    return {
      items: [
        {item: 'One', C: <Item>One</Item>}, 
        {item: 'Two', C: <Item>Two</Item>}
      ],
      order: ['One', 'Two']
    };
  },
  swap () {
    this.setState({
      order: [this.state.order[1], this.state.order[0]]
    });
  },
  render: function () {
    return <div>
      <button onClick={this.swap}>Swap</button>
      <div style={{position: 'relative'}}>
       {this.state.items.map(x => 
          React.cloneElement(x.C, { 
            index: this.state.order.findIndex(z => z === x.item) 
          }))
       }
      </div>
    </div>;
  }
});

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

为什么Webpack代码拆分无法按预期进行?

来自分类Dev

为什么clone()无法按预期工作?

来自分类Dev

为什么diff无法按预期工作?

来自分类Dev

为什么_.isEqualWith()无法按预期工作?

来自分类Dev

为什么setSlideCount无法按预期工作?

来自分类Dev

为什么clone()无法按预期工作?

来自分类Dev

为什么umask无法按预期工作?

来自分类Dev

为什么按位OR和AND逻辑无法按预期工作?

来自分类Dev

为什么MobX v6.x无法在带有Typescript的React中按预期工作?

来自分类Dev

为什么这不能按预期进行串联?

来自分类Dev

为什么这不能按预期进行串联?

来自分类Dev

为什么linq不能按预期进行分组/计数

来自分类Dev

为什么我的程序无法按预期运行?

来自分类Dev

为什么IntelliSense在foreach循环中无法按预期工作?

来自分类Dev

为什么Android数据绑定库无法按预期工作?

来自分类Dev

为什么此同步方法无法按预期工作?

来自分类Dev

为什么Nokogiri的xpath无法按预期工作?

来自分类Dev

为什么简单的haskell add函数无法按预期运行?

来自分类Dev

为什么递归中的std :: ofstream无法按预期工作?

来自分类Dev

为什么setInterval(-> ...),0无法按预期运行?

来自分类Dev

为什么DateTime :: sub无法按预期工作?

来自分类Dev

为什么asyncio.Queue无法按预期工作?

来自分类Dev

为什么此验证代码无法按预期工作?

来自分类Dev

为什么项目集无法按预期工作?

来自分类Dev

为什么我的lambda函数无法按预期运行?

来自分类Dev

为什么system(“ clear”)命令无法按预期方式工作?

来自分类Dev

为什么此C#代码无法按预期运行?

来自分类Dev

为什么模拟补丁无法按预期工作?

来自分类Dev

为什么导航器pushNamedAndRemoveUntil无法按预期工作?

Related 相关文章

  1. 1

    为什么Webpack代码拆分无法按预期进行?

  2. 2

    为什么clone()无法按预期工作?

  3. 3

    为什么diff无法按预期工作?

  4. 4

    为什么_.isEqualWith()无法按预期工作?

  5. 5

    为什么setSlideCount无法按预期工作?

  6. 6

    为什么clone()无法按预期工作?

  7. 7

    为什么umask无法按预期工作?

  8. 8

    为什么按位OR和AND逻辑无法按预期工作?

  9. 9

    为什么MobX v6.x无法在带有Typescript的React中按预期工作?

  10. 10

    为什么这不能按预期进行串联?

  11. 11

    为什么这不能按预期进行串联?

  12. 12

    为什么linq不能按预期进行分组/计数

  13. 13

    为什么我的程序无法按预期运行?

  14. 14

    为什么IntelliSense在foreach循环中无法按预期工作?

  15. 15

    为什么Android数据绑定库无法按预期工作?

  16. 16

    为什么此同步方法无法按预期工作?

  17. 17

    为什么Nokogiri的xpath无法按预期工作?

  18. 18

    为什么简单的haskell add函数无法按预期运行?

  19. 19

    为什么递归中的std :: ofstream无法按预期工作?

  20. 20

    为什么setInterval(-> ...),0无法按预期运行?

  21. 21

    为什么DateTime :: sub无法按预期工作?

  22. 22

    为什么asyncio.Queue无法按预期工作?

  23. 23

    为什么此验证代码无法按预期工作?

  24. 24

    为什么项目集无法按预期工作?

  25. 25

    为什么我的lambda函数无法按预期运行?

  26. 26

    为什么system(“ clear”)命令无法按预期方式工作?

  27. 27

    为什么此C#代码无法按预期运行?

  28. 28

    为什么模拟补丁无法按预期工作?

  29. 29

    为什么导航器pushNamedAndRemoveUntil无法按预期工作?

热门标签

归档