reactjs – 为什么React的DOM协调不能按预期工作?
我正在尝试使用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>; } }); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |