2017-06-05 56 views
2

我有一個高分列表,每分鐘會自動更新一次當前分數。然後它用this.setState({ data: newData });更新組件。元素無法在React中的css轉換狀態更改

我在sort以下的新數據按分數運行,每個項目通過map更新其style.top

的Javascript

... 

let current = this.state.data.sort((a,b) => { 
    if(a.score < b.score) return -1; 
    if(a.score > b.score) return 1; 
    return 0; 
}); 

let items = current.map((item,i) => { 
    return (
    <div 
     key={item.name} 
     className="item" 
     style={{ top: (i*30) + 'px', backgroundColor: item.color }}> 
     {item.name} 
    </div> 
); 
}); 

return (
    <div> 
    {items} 
    </div> 
); 

CSS

.item { 
    position: absolute; 
    transition: top 1s; 
} 

我想要的物品動畫上下它們的新位置,但這種情況不會發生。瀏覽器似乎記住了DOM的部分內容,但不包括其他內容。

React似乎明白哪個項目是通過使用唯一鍵,如果我使用React Developer Tools進行檢查,但實際的DOM沒有。

即使是陌生人,只有列表中移動的物品(較高的分數)似乎被記住。向下移動的項目被重新創建,因此轉換不起作用。他們只是在不轉換到新職位的情況下流行起來。

Here is a working example to demonstrate. (JSFiddle)

回答

1

如果您更改它以便在渲染週期之間不重新排序項目,但總是以不同的頂部樣式以相同的順序渲染它,它會正確地進行動畫。我認爲這是因爲更改元素的順序會迫使它們從DOM中刪除並通過反應重新添加。

相關的代碼是:

render() { 
    let current = this.state.data.slice().sort((a,b) => { 
     if(a.score < b.score) return -1; 
     if(a.score > b.score) return 1; 
     return 0; 
    }); 

    let items = this.state.data.map(item => { 
     let position = current.indexOf(item); 
     return (
      <div 
      key={item.name} 
      className="item" 
      style={{ top: (position*30) + 'px', backgroundColor: item.color }}> 
       {item.name} 
      </div> 
     ); 
    }); 

    return (
     <div> 
     {items} 
     </div> 
    ); 
} 

Updated demo

+0

這是完美的!謝謝! –

1

陣營重繪您更新DOM元素。這將解決真正奇怪的行爲,例如閃爍,跳躍等。

在開始使用光纖之前,React團隊爲此提供了一些解決方案。隨着光纖的發佈,我希望我們會看到對轉換和動畫的更好支持。

在此之前,我建議您使用外部庫作爲動畫,如: https://github.com/FormidableLabs/react-animations對於一般動畫。

https://github.com/reactjs/react-transition-group用於元素進入和退出DOM。