記憶をなくした時のためのメモ。
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
公式に良いサンプルがあったので、そのまま貼り付けます。
おわり

コメント