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