加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

reactjs – 为什么React的DOM协调不能按预期工作?

发布时间:2020-12-15 20:31:24 所属栏目:百科 来源:网络整理
导读:我正在尝试使用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'}} {it
我正在尝试使用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

解决方法

警告:我在这个答案中做了一些假设,然而它会照亮你的一些(以及我之前的)问题.我的解决方案几乎肯定可以简化,但为了回答这个问题,它应该是足够的.

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

如果你看一下,你可以看看React是什么.第二个元素根本没有改变它的样式支柱,只是交换内部文本节点,而第一个元素作为新元素被放入dom中.

如果我不得不猜测,这是因为在数组中交换两个项目的方式有效,其中至少有一个项目被复制到临时变量并放回到数组中.

我想也许如果你使翻译随机,这两个元素都会得到新的风格道具和动画,但这只会使它更清晰,这不是预期的行为.

在寻找解决方案的途中:

作为一个实验,如果我们提前创建节点,并通过React.cloneElement在渲染中传递索引prop,该怎么办?当我们在它时,让我们渲染一个跨度,如果索引=== 0,否则为div.无需担心的钥匙.

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>;
  }
});

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读