react-transition-group の使い方
react-transition-group@^2
で提供されているコンポーネントは
- Transition
- CSSTransition
- TransitionGroup
の3つです。
Transition
Transition
は以下のようなプロパティを取ります。
children
には(status: 'entering' | 'entered' | 'exiting' | 'exited') => JSX.Element
が渡されます。このstatus
の状態を使ってクラス名や何かしらの属性を内部の要素に設定し、CSSなどを使ってアニメーションさせることができます。
in
は内部コンポーネントを表示するかどうかです。in
がfalse
の時はexiting
からexited
に向かい、true
の時はentering
からentered
に向かいます。1番最初は単に-ing
なしでentered
かexited
が直接設定されます。
timeout
は、status
が-ing
である状態の時間(msec)を指定します。これはaddEndListener
を設定しない場合は必須になります。addEndListener
は動的にtimeout
時間を設定したい場合に使えます。例えば CSS のtransition
でアニメーションするような場合、その終わりにtransitionend
イベントが発火しますが、その発火するまでの時間を使うことでtimeout
の代わりとすることができます。(修正箇所も減る)これは第一引数にchildren
関数での戻り値の要素が渡り、第二引数では-ing
の終わりということになるdone
関数が渡ってきます。この渡ってきたルート要素からアニメーションする要素を取得し、transitionend
イベントでdone
を読んで、-ing
を終えるといったことができます。注意点として、このaddEndListener
はin
が変わるたびに毎回実行されます。そのためイベントの登録などをしている場合、実行回数分登録することになってしまうので、毎回done
を呼ぶタイミングでイベントの解除模するといいと思います。
mountOnEnter
はin
がtrue
になるまでマウントしなかったり、unmountOnExit
はexited
になる度アンマウントする為のプロパティです。消える時はアニメーションしなくていいみたいな場合に使うといい感じです。
またonEntered
やonExited
などを渡して完了した時に連動してある処理を行うこともできます。ほかに、
- 直前の
onEnter
,onExit
-ing
のonEntering
,onExiting
があります。
CSSTransition
内部的にはある程度設定済みのTransition
です。与えられたTransition
と同様のin
やtimeout
やこのコンポーネント独自のclassNames
を元に主により高機能なクラス名の管理を行ってくれます。与えたclassNames
にサフィックスとして-enter
, -enter-active
, -enter-done
, -exit
, -exit-active
, -exit-done
, -appear
, -appear-active
がルート要素に付くようになるので、それらのクラス名を使って CSS でアニメーションを設定します。
サフィックスの名前は以下のような状態だと思うといいかなと思います。
-enter
と-exit
はTransition
の-ing
が付く直前に付き、-done
が付く時取り除かれる- または
onEnter
とonExit
は呼ばれたタイミングからonEntered
やonExited
が呼ばれるタイミングまで
- または
-enter-active
と-exit-active
はTransition
の-ing
の別名-enter-done
と-exit-done
はTransition
の-ed
の別名
TransitionGroup
1つ1つがTransition
を持つような配列要素をレンダリングしたい時にそれらをラップするように使うだけです。注意点は2つあります。まず、各配列のルート要素はTransition
である必要があります。2つ目はTransition
にはin
ではなくkey
が必須です。またこれはユニークな値である必要があります。in
はTransitionGroup
がkey
から有無を判定して自動で設定してくれるので考えないで済みます。
import {TransitionGroup} from 'react-transition-group';
(() => {
<TransitionGroup>
{items.map(item => {
return
<CSSTransition key={item.id}>{
status => {
/* ... */
}
}</CSSTransition>
);
})
</TranitionGroup>
})();