警告:我做這個答案的一些假設,但它閃耀光你的一些(以前我的)問題。我的解決方案几乎肯定可以簡化,但爲了回答這個問題,它應該是足夠的。
這是一個很好的問題。我有些驚訝地打開開發工具,看看交換項目時發生了什麼。
如果你看看,你可以排序看看React是什麼。第二個元素根本不改變它的樣式屬性,只是交換內部文本節點,而第一個元素作爲一個新元素放入dom中。
如果我不得不猜測,這是因爲交換數組中兩個項目的方式起作用,其中至少有一個項目被複制到一個臨時變量並放回到數組中。
我認爲,也許如果你隨機翻譯,兩個元素都會得到新的樣式道具和動畫,但這只是使它更清楚,這不是預期的行爲。
在路上找到一個解決辦法:
作爲一個實驗,如果我們創造了什麼節點時間提前,並通過指數支撐在通過React.cloneElement
渲染。雖然我們在這裏,但如果使用index === 0
和div
,我們將渲染一個span
。沒有鑰匙擔心。
http://codepen.io/alex-wilmer/pen/pbaXzQ?editors=1010
開放的開發工具,現在說明什麼反應的打算。 React保存了元素,只改變了相關的部分,在這裏是innerText節點和元素類型。因爲樣式正好以1:1交換,所以不需要樣式更新。
解決方案:
可以生成你的反應的元素的時間提前,讓那些在一個陣列,這樣沒有鑰匙洗牌周圍,並找出如何放置回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>;
}
});
反應的表現,因爲它應該是沒有保證的元素將*留在DOM *,只是它會優化什麼可以。你需要的是React的[ReactCSSTransitionGroup](https://facebook.github.io/react/docs/animation.html)。 –
ReactCSSTransitionGroup用於創建進入/離開動畫。從圖書館的文檔:「[它] ...是React組件進入或離開DOM時執行CSS轉換和動畫的簡單方法」。我不確定這對重新排序動畫是否有用。 –
完全正確,我以爲我之前用它來重新排序。對不起,誤導:) –