Reactでアニメーションさせたい

# Reactでアニメーションさせたい
Reactで簡単なアニメーションをさせたいと思い、実際に作るまでに調査したこと・簡単なサンプルをメモしておく

## やりたいこと
- 何かデータを保存した時や削除した時に、左下とかに保存・削除したことをクライアントに通知したい

## 調査
- 「React アニメーション」で調べてみたところプラグインを使うと実現出来るとのこと
- [Reactドキュメント](https://reactjs.org/docs/animation.html)は、`react-transition-group`を勧めている
  - `ReactTransitionGroup`と`ReactCSSTransitionGroup`は、コミュニティによって、管理されている`react-transition-group`パッケージに移動したとのこと
  - 他にもいくつかプラグインが存在していたが、そこまで複雑なことをするつもりもなかったので、公式が勧めているものを使うことに
-  `react-transition-group`とは
  -  ReactコンポーネントがDOMに出入りする時にCSSトランジションとアニメーションを実行するのを簡単に実装出来るようにしてくれる

## サンプル
### インストール
```shell
$ yarn add react-transition-group
```

### 実装
#### jsx

```jsx
import React from 'react';
import {CSSTransition} from 'react-transition-group';

class NotificationMessageModal extends React.PureComponent {
  constructor(props) {
    super(props);
    this.onEntered = this.onEntered.bind(this);
  }
  onEntered() {
    this.props.notifyState({
      showNotificationMessageModal: false
    });
  }

  render() {
    return (
      <div>
        <CSSTransition
          in={this.props.showModal}
          classNames={this.props.className}
          timeout={this.props.timeout}
          onEntered={this.onEntered}
          >
            <p className={this.props.className}>{this.props.message}</p>
        </CSSTransition>
      </div>
    );
  }
}

export default NotificationMessageModal;
```

- in
  - `true or false`
  - `true`を代入すると、トランジション開始
- classNames
  - `string`
  - classNameを指定する
  - `fade`を指定すると、`fade-enter`, `fade-enter-active`, `fade-enter-done,` `fade-exit`, `fade-exit-active`, `fade-exit-done`, `fade-appear`, and `fade-appear-active`が適用される
    - どういうアニメーションをさせるか上記のクラス名にCSSをあてることで実現可能
- timeout
  - `number`
  - タイムアウト時間を指定
- onEnterd
  - `function`
  - `in`で`true`を指定したタイミングでアニメーションが完了したタイミングで実行したい処理を追加する際に使用する



#### css

```css
.notification {
  display: inline-block;
  padding: 10px;
  background: #6699CC;
  color: #666666;
  text-align: center;
  margin: 10px 0 0;
  padding: 15px;
  min-width: 200px;
  position: fixed;
  border: 1px solid #bfbfbf;
  border-radius: 5px;
  left: 50px;
  bottom: 50px;
  z-index: 9999;
}
.notification-enter {
  opacity: 0;
}
.notification-enter-active {
  opacity: 1;
  transition: all 1000ms ease-out;
}
.notification-exit-done {
  opacity: 0;
  transition: all 3000ms cubic-bezier(1.0, 0, 1.0, 1.0);
}
```

## 備考
- CSSトランジション
  - CSSプロパティが変化する際のアニメーション速度を操作する手段
- classNamesの詳細
  - enter: 追加時（`in`が`true`になった時）
  - enter-active: 追加中
  - enter-done: 追加完了後
  - exit: 削除時（`in`が`false`になった時）
  - exit-active: 削除中
  - exit-done: 削除完了後
  - appear: マウント時
  - appear-active: マウント中
- onEntered以外の指定可能な関数
  - onEnter: 追加時
  - onEntering: 追加中
  - onEntered: 追加完了後
  - onExit: 削除時
  - onExiting: 削除中
  - onExited: 削除完了後
- CSSのtransition
  - transition-property: transitionを適用するCSSプロパティを指定
  - transition-duration: 変化にかかる時間を指定する
  - transition-timing-function: 変化のタイミング・進行割合を指定する
      - [指定可能なプロパティ](https://easings.net/ja)
  - transition-delay: 変化がいつ始まるかを指定する
- 参考記事
  - [公式ドキュメント](https://reactcommunity.org/react-transition-group/css-transition)
  - [Reactの公式ドキュメント](https://reactjs.org/docs/animation.html)
  - [他の方の記事](http://hydro-pump.hatenablog.com/entry/2018/05/18/061601)