react-transition-groupの使い方メモ

記憶をなくした時のためのメモ。

react-transition-groupとは?

Reactでアニメーションを管理するためのライブラリです。

ただし、react-transition-group自体はアニメーション機能は提供していません。

react-transition-groupは「自分の書いたアニメーションを管理するためのライブラリ」であって、「アニメーションの機能を提供してくれるライブラリ」ではありません。

なので、アニメーションのCSSは自分で書かないといけません。

公式React Transition Group

具体的に何ができる?

すごく大雑把に言えば

  • 設定したstateが falsetrue になったら指定したclassを付与する
  • 設定したstateが truefalse になったら指定したclassを付与したのちに要素を削除する(もしくは削除しない)

みたいなことができるライブラリです。

4つのコンポーネント

公式に書いている通りですが、react-transition-groupでは

  • Transition
  • CSSTransition
  • SwitchTransition
  • TransitionGroup

という4つのコンポーネントが提供されています。

違い

前半2つは

  • 設定したstateが falsetrue になったら指定したclassを付与する
  • 設定したstateが truefalse になったら指定したclassを付与したのちに要素を削除する(もしくは削除しない)

みたいなことができるコンポーネントです。

 

後半2つは、前半2つを管理するためのコンポーネントです。

Transition と CSSTransitionの違い

CSSTransition は、Transitionの上位互換です。

TransitionでできることはCSSTransitionでも出来ます。

違いは

  • CSSTransitionではclassNamesという属性を指定できる
  • CSSTransitionではappearという遷移状態も追加される

の2点かと思われます。(後述します)

SwitchTransition と TransitionGroupの違い

  • 共通点:
    • 複数のTransitionCSSTransitionを管理するためのコンポーネント
  • 違い:
    • 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
  • animatefalseにすると・・・
    • stateexitingexitedと2秒かけて変化する
    • このgif動画ではunmountOnExittrueに設定しているため、exitedになった瞬間に要素自体も削除されるので、exitedは表示されていません
  • animatetrueにすると・・・
    • stateenteringenteredと2秒かけて変化する

 

以下、補足です。

  • TransitionコンポーネントにunmountOnExit={false}を指定すると、animatefalseにしたあとも要素が残り続ける
    • unmountOnExit={true}を指定すると、exitedに変化すると同時に要素自体も消える
      (ちなみにこの場合はunmountOnExit={true}をとわざわざtrueを指定しなくてもunmountOnExitだけでいい)
  • animateを最初からtrueに指定すると、最初からマウントされた状態(entered)からスタートする
    • animateを最初からtrueに指定した状態で、Transitionコンポーネントにappear={true}を指定すると、最初のマウント時にenteringenteredが実行されるようになる
  • timeoutの部分は、オブジェクトで指定することで個別に設定できる
    • 例えば、以下のように指定したりもできる。
      timeout={{
       appear: 500, //appearは最初にマウントされるときの秒数
       enter: 300,
       exit: 500,
      }}

 

このようにTransitionでは、inの値がtruefalseを切り替わることでstateが変化します。

この「stateが変化する」を特性を利用して「アニメーションに応用してね!」というのがTransitionコンポーネントです。

CSSTransition

さきほどのコードをCSSTransitionに変更したとしても、同じように動きます。

このようにCSSTransitionTransitionの上位互換なので、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>
    </>
  );

CSSTransition

例えば、 classNames="fade"と指定した状態で、inの値をfalsetrueに変更すると

fade-enter fade-enter-active

fade-enter-done

というクラスが付与されます。

 

逆に、inの値をtruefalseに変更すると

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>
    </>
  );

 

こんな感じで、CSSTransactioninを指定しなくても「要素が追加されたら自動的にクラスが付与される」みたいな挙動になります。

SwitchTransition

公式に良いサンプルがあったので、そのまま貼り付けます。

 

おわり

React
スポンサーリンク
この記事を書いた人
penpen

1991生まれ。
2019年くらいからフロントエンドエンジニアを目指している元アフィリエイターです💩

penpenをフォローする
penpenをフォローする
penpenメモ

コメント

タイトルとURLをコピーしました