スコア順に並べられたアイテムのリストがあり、react.jsによって、長方形のアイテムの垂直方向のリストとしてレンダリングされています(一番上のスコア)。個々のアイテムをホバーなどでクリックすると、追加情報が表示/非表示になり、垂直方向の高さが変わります。
スコアをわずかに変更する新しい情報が到着し、再ソート後に一部のアイテムのランクが高くなり、その他のアイテムのランクが低くなります。すぐに新しい場所に表示されるのではなく、アイテムを新しい位置に同時にanimateしたいです。
React.jsでこれを行うための推奨される方法はありますか、おそらく人気のあるアドオンを使用しますか?
(D3を使用した同様の過去の状況で、私が使用した手法はおおよそ次のとおりでした。
今、私はReactっぽい方法で同様の効果を期待しています...)
私はちょうどこの問題に取り組むモジュールをリリースしました
https://github.com/joshwcomeau/react-flip-move
マジックムーブ/シャッフルとは異なるいくつかのことを行います:
デモをご覧ください:
http://joshwcomeau.github.io/react-flip-move/examples/#/shuffle
React Shuffleは堅牢で最新のものです。 Ryan Florences Magic Moveデモに触発された
これは少し古い質問であり、おそらく今までに解決策を見つけたと思いますが、この質問に出くわした人は、ライアンフローレンスのMagicMoveライブラリをチェックしてください。 Reactあなたが記述する正確なシナリオを処理するためのライブラリ: https://github.com/ryanflorence/react-magic-move
実際にご覧ください: https://www.youtube.com/watch?v=z5e7kWSHWTg#t=424
編集:これはReact 0.14で壊れています。以下のTim Arneyによって提案された代替案として React Shuffle を参照してください。
私が頭の中でこれを達成するために私が考えることができる最良の方法は、最初に、ここで説明するようにあなたの要素のすべてにキーを与えることを確認することです。
http://facebook.github.io/react/docs/multiple-components.html#dynamic-children
次に、次のようなCSS3アニメーションを定義します。
基本的にレンダー関数では、要素の配置場所を計算します。ReactJSは、要素を配置する場所に配置します(各要素に毎回同じキーを指定してください!これは、ReactJSがDOM要素を再利用するために重要です正しく)。少なくとも理論的には、reactjs/javascript以外のアニメーションの残りの部分はCSSが処理する必要があります。
Disclamer ...私は実際にこれを試したことがない;)
アニメーションにサードパートライブラリを使用したくなかったため、「 [〜#〜] flip [〜#〜] 」を実装しましたReactライフサイクルメソッドgetSnapshotBeforeUpdate()およびcomponentDidUpdate()を使用したアニメーション手法。
リストアイテムのprops.indexが変更されると、古い位置がgetSnapshotBeforeUpdate()およびcomponentDidUpdate()でキャプチャされ、css transform:translateY()が適用され、アイテムが古い位置から現在の位置にアニメーション表示されます。
class TreeListItem extends Component {
constructor(props) {
super(props);
this.liRef = React.createRef();
}
getSnapshotBeforeUpdate(prevProps) {
if (prevProps.index !== this.props.index) {
// list index is changing, prepare to animate
if (this.liRef && this.liRef.current) {
return this.liRef.current.getBoundingClientRect().top;
}
}
return null;
}
componentDidUpdate(prevProps, prevState, snapshot) {
if (prevProps.index !== this.props.index && snapshot) {
if (this.liRef && this.liRef.current) {
let el = this.liRef.current;
let newOffset = el.getBoundingClientRect().top;
let invert = parseInt(snapshot - newOffset);
el.classList.remove('animate-on-transforms');
el.style.transform = `translateY(${invert}px)`;
// Wait for the next frame so we
// know all the style changes have
// taken hold.
requestAnimationFrame(function () {
// Switch on animations.
el.classList.add('animate-on-transforms');
// GO GO GOOOOOO!
el.style.transform = '';
});
}
}
}
render() {
return <li ref={this.liRef}>
</li >;
}
}
class TreeList extends Component {
render() {
let treeItems = [];
if (this.props.dataSet instanceof Array) {
this.props.dataSet.forEach((data, i) => {
treeItems.Push(<TreeListItem index={i} key={data.value} />)
});
}
return <ul>
{treeItems}
</ul>;
}
}
.animate-on-transforms {
/* animate list item reorder */
transition: transform 300ms ease;
}
要素の位置はDOMエンジンに大きく依存しているため、Reactコンポーネント内で純粋な方法でトゥイーンとアニメーションを実装することは非常に難しいと思います。少なくとも、要素の現在位置を保持するストア、要素の次の位置を保持する(または前のストアと結合する)ストア、および要素ごとにオフセットマージンを適用するrender()メソッドが必要です。最初の場所で次の位置を計算する方法も課題ですが、要素が位置のみを交換する場合、現在の位置でストアを使用して要素#0を交換できます要素#1、次の位置でオフセットを交換します。
最終的には、外部ライブラリを使用して、レンダリング後に要素のマージンを操作する方が簡単です。