framer-motionとreact-routerを組み合わせたお手軽ページトランジション
Reactでページ遷移時のトランジションを実装しよう!となった時に思い浮かぶのはreact-transition-group
を使ったトランジションでしょう。ですが、react-transtion-groupは出現、消滅する際に付与するclassNameを指定して使うため、コンポーネント間でCSSの依存ができたり、他の箇所はCSS in JSを使っているのにトランジションをつけるためにcssファイルを設置したりなど難が多い印象があります。
本記事ではそういった課題を解決できるframer-motionというライブラリを使ったページトランジションの実装例をお伝えします。実践的なケースを想定しルーターにはreact-routerを利用します。
サンプル
サンプルアプリには/
と/about
にそれぞれHome、Aboutというコンポーネントがあり、コンポーネントが切り替わるたびにアニメーションします。
また、Homeにおいてある「OpenDialog」のリンクを押すことでダイアログが出現する形にしています。ダイアログに関してはクエリパラメータで識別する形にして、ブラウザのバックボタンで閉じれる実装になっています。
実装のポイント
FramerMotionの基礎的なものに関してはドキュメントを参考にしてください。
react-routerとアニメーション
framer-motionの提供するAnimatePresenceとmotionのコンポーネントを利用すると、コンポーネントのアンマウント時にアニメーションをつけられます。すると、motionのexitに渡した状態になるアニメーションをしてアンマウントされます。 注意点ですが、その際にAnimatePresenceの子にあたるmotionコンポーネントにkeyプロパティをつけるのを忘れないようにしましょう。react-routerに関してはSwitchコンポーネントにkeyを指定する必要があります。
クエリパラメータを利用したアニメーション
実際のケースとしては少ないかもしれませんが、ダイアログにURLを付与しています。事前の画面をoverlapするフォームといった画面としったものを想定しています。 今回はlocation.searchからクエリパラメータを取得し、その有無でコンポーネントの出し分けをしています。AnimatePresenceとmotionを使うことでアニメーションがつくので特に難しいポイントはないと思います。
AnimatePresenceのprops
サンプルコード中ではinitialにfalseを指定しています。initialをtrueにすると画面の初期表示の際にもアニメーションが実行されます。 また、exitBeforeEnterはAコンポーネントが消えてBコンポーネントが出現する際に、Aのexit→Bのenterといった順に実行されます。このpropsを指定しないとexitとenterが同時に発火されます。