記憶をなくした時のためのメモ。
react-transition-groupとは?
Reactでアニメーションを管理するためのライブラリです。
ただし、react-transition-group自体はアニメーション機能は提供していません。
react-transition-groupは「自分の書いたアニメーションを管理するためのライブラリ」であって、「アニメーションの機能を提供してくれるライブラリ」ではありません。
なので、アニメーションのCSSは自分で書かないといけません。
具体的に何ができる?
すごく大雑把に言えば
- 設定したstateが false → true になったら指定したclassを付与する
- 設定したstateが true→ false になったら指定したclassを付与したのちに要素を削除する(もしくは削除しない)
みたいなことができるライブラリです。
4つのコンポーネント
公式に書いている通りですが、react-transition-groupでは
- Transition
- CSSTransition
- SwitchTransition
- TransitionGroup
という4つのコンポーネントが提供されています。
違い
前半2つは
- 設定したstateが false → true になったら指定したclassを付与する
- 設定したstateが true→ false になったら指定したclassを付与したのちに要素を削除する(もしくは削除しない)
みたいなことができるコンポーネントです。
後半2つは、前半2つを管理するためのコンポーネントです。
Transition と CSSTransitionの違い
CSSTransition
は、Transition
の上位互換です。
Transition
でできることはCSSTransition
でも出来ます。
違いは
CSSTransition
ではclassNames
という属性を指定できるCSSTransition
ではappear
という遷移状態も追加される
の2点かと思われます。(後述します)
SwitchTransition と TransitionGroupの違い
- 共通点:
- 複数の
Transition
とCSSTransition
を管理するためのコンポーネント
- 複数の
- 違い:
SwitchTransition
:古い要素のアニメーションが終わってから新しい要素のアニメーションを行うTransitionGroup
:古い要素のアニメーションと新しい要素のアニメーションを同時に行う
使い方
Transition
Transition
コンポーネントの子要素にstate
が渡ってきます。
import { Transition } from "react-transition-group"; function App() { const [animate, setAnimate] = useState(false); return ( <> <button onClick={() => setAnimate((prev) => !prev)}> {animate ? "falseにする" : "trueにする"} </button> <Transition in={animate} timeout={2000} unmountOnExit> {(state) => { return <h1 style={{ backgroundColor: "red" }}>{state}</h1>; }} </Transition> </> );
|
以下、補足です。
- Transitionコンポーネントに
unmountOnExit={false}
を指定すると、animate
をfalse
にしたあとも要素が残り続けるunmountOnExit={true}
を指定すると、exited
に変化すると同時に要素自体も消える
(ちなみにこの場合はunmountOnExit={true}
をとわざわざtrue
を指定しなくてもunmountOnExit
だけでいい)
animate
を最初からtrue
に指定すると、最初からマウントされた状態(entered
)からスタートするanimate
を最初からtrue
に指定した状態で、Transition
コンポーネントにappear={true}
を指定すると、最初のマウント時にentering
→entered
が実行されるようになる
timeout
の部分は、オブジェクトで指定することで個別に設定できる- 例えば、以下のように指定したりもできる。
timeout={{ appear: 500, //appearは最初にマウントされるときの秒数 enter: 300, exit: 500, }}
- 例えば、以下のように指定したりもできる。
このようにTransition
では、in
の値がtrue
↔false
を切り替わることでstate
が変化します。
この「state
が変化する」を特性を利用して「アニメーションに応用してね!」というのがTransition
コンポーネントです。
CSSTransition
さきほどのコードをCSSTransition
に変更したとしても、同じように動きます。
このようにCSSTransition
はTransition
の上位互換なので、Transition
の代わりとしても使えます↓。
import { CSSTransition } from "react-transition-group"; function App() { const [animate, setAnimate] = useState(false); return ( <> <button onClick={() => setAnimate((prev) => !prev)}> {animate ? "falseにする" : "trueにする"} </button> <CSSTransition in={animate} timeout={2000} unmountOnExit> {(state) => { return <h1 style={{ backgroundColor: "red" }}>{state}</h1>; }} </CSSTransition> </> );
ただ、このような使い方は(おそらく)しません。
CSSTransition
では以下のようにclassNames
を使います。
import { CSSTransition } from "react-transition-group"; function App() { const [animate, setAnimate] = useState(true); return ( <> <h2>現在のanimate:{animate ? "true" : "false"}</h2> <button onClick={() => setAnimate((prev) => !prev)}> {animate ? "falseにする" : "trueにする"} </button> <CSSTransition in={animate} timeout={2000} unmountOnExit classNames="fade" > <div> ←ここにclassが付与される <h2 style={{ backgroundColor: "red" }}>タイトルです</h2> </div> </CSSTransition> </> );
例えば、 classNames="fade"
と指定した状態で、in
の値をfalse
→true
に変更すると
fade-enter fade-enter-active
↓
fade-enter-done
というクラスが付与されます。
逆に、in
の値をtrue
→false
に変更すると
fade-exit fade-exit-active
↓
fade-exit-done
というクラスが付与されます。
また、Transactionと違って
in={true}
appear={true}
の両方を指定することで、初回のマウント時のみ
fade-appear fade-appear-active
↓
fade-appear-done
が付与されるようになります。
このようにTransition
では、classNames
に設定した文字列がクラス名として付与されるようになります。
なのでそのクラス名のCSSをあらかじめ用意しておくと、目的のアニメーションを実現できます。
TransitionGroup
説明がムズかしいので、まず以下のコードを見てください。
function App() { const [dataList, setDataList] = useState(["あ", "い", "う"]); const textRef = useRef(null); return ( <> <p> <input type="text" name="name" ref={textRef} /> </p> <button onClick={() => setDataList((prev) => [...prev, textRef.current.value])} > 追加する </button> <TransitionGroup> {dataList.map((data,i) => { return ( <CSSTransition key={i} timeout={3000} unmountOnExit classNames="fade" > <div> <h3 style={{ backgroundColor: "red" }}>{data}</h3> </div> </CSSTransition> ); })} </TransitionGroup> </> );
こんな感じで、CSSTransaction
でin
を指定しなくても「要素が追加されたら自動的にクラスが付与される」みたいな挙動になります。
SwitchTransition
公式に良いサンプルがあったので、そのまま貼り付けます。
おわり
コメント