Reactは動的ポップアップウィンドウコンポーネントを実装します

Reactは動的ポップアップウィンドウコンポーネントを実装します

UI コンポーネントを作成するときに、アニメーションを考慮しなければ、アニメーションを実現するのは非常に簡単です。主なことは、存在の有無 (Vue の v-if 属性に類似) または可視性 (Vue の v-show 属性に類似) を切り替えることです。

1. アニメーションなしのポップアップ

React では、これを次のように実現できます。

インターフェース ModalProps {
  開く: ブール値;
  onClose?: () => void;
  子供はいますか?: いません;
}
定数モーダル = ({open.onClose, children}: ModalProps) => {
  開く場合
    null を返します。
  }
  createPortal を返します(<div>
    <div classname="modal-content">{子}</div>
    <div classname="modal-close-btn" onclick="{onClose}">x</div>
  </div>, ドキュメント.body);
};

方向:

定数App = () => {
  定数[open, setOpen] = useState(false);

  戻る (
    <div クラス名="app">
      <button onclick="{()" ==""> setOpen(true)}>モーダルを表示</button>
      <modal open="{open}" onclose="{()" ==""> setOpen(false)}>
        モーダルコンテンツ
      </モーダル>
    </div>
  );
};

ここではopen属性を使用して表示するかどうかを制御していますが、グラデーション効果はまったくありません。

フェードやズームなどのアニメーション効果を実現したい場合は、これを変更する必要があります。

2. アニメーションポップアップを自分で作成する

多くの学生がアニメーション効果を自分で実装すると、アニメーションは表示されているときには機能するが、閉じているときには機能しないことに気付くことがよくあります。それはすべて、アニメーションのタイミングがうまく制御されていなかったためです。ここでは、まず動的エフェクトのフローを独自に実装します。

最初に実装を始めたとき、アニメーションには開始状態と終了状態しかなく、アニメーションを制御するには多くの変数とロジックが必要でした。

その後、アニメーションを複数の部分に分割し、各部分を個別に制御するreact-transition-groupコンポーネントの実装を参照しました。

  1. 拡張アニメーションの順序: enter -> enter-active -> enter-done;
  2. アニメーション効果を閉じる順序: exit -> exit-active -> exit-done;

アニメーションプロセスは、 enter-activeexit-activeのプロセスにあります。

閉じるアニメーションが実行されたかどうかを制御するには変数 active を使用し、パラメーター open は展開アニメーションが実行されるか閉じるアニメーションが実行されるかのみを制御します。

ポップアップ ウィンドウは、open と active の両方が false の場合にのみ破棄されます。

const モーダル = ({ open, children, onClose }) => {
  const [active, setActive] = useState(false); // ポップアップウィンドウの存在サイクル if (!open && !active) {
    null を返します。
  }

  ReactDOM.createPortal() を返す
    <div クラス名="モーダル">
      <div classname="modal-content">{子}</div>
      <div classname="modal-close-btn" onclick="{onClose}">
        x
      </div>
    </div>,
    文書本文、
  );
};

ここでは、アニメーション プロセスに変更を加え続けます。

const [aniClassName, setAniClassName] = useState(''); // アニメーションクラス

// 遷移実行完了リスニング関数 const onTransitionEnd = () => {
  // open が rue の場合、終了状態は 'enter-done' です
  // open が false でない場合、終了ステータスは 'exit-done' になります
  setAniClassName(open ? 'enter-done' : 'exit-done');

  // open が false の場合、アニメーションが終了するとポップアップウィンドウのライフサイクルも終了します if (!open) {
    アクティブに設定します(false);
  }
};

使用効果(() => {
  (開く)の場合{
    アクティブに設定します(true);
    アニクラス名を設定します('enter');
    // setTimeout はクラスを切り替えて遷移を起こすために使用されます setTimeout(() => {
      setAniClassName('enter-active');
    });
  } それ以外 {
    アニクラス名を設定します('終了');
    タイムアウトを設定する(() => {
      setAniClassName('exit-active');
    });
  }
}、 [開ける]);

Modal コンポーネントの完全なコードは次のとおりです。

const モーダル = ({ open, children, onClose }) => {
  const [active, setActive] = useState(false); // ポップアップウィンドウの存在サイクル const [aniClassName, setAniClassName] = useState(''); // アニメーションクラス
  定数 onTransitionEnd = () => {
    setAniClassName(open ? 'enter-done' : 'exit-done');
    開く場合
      アクティブに設定します(false);
    }
  };

  使用効果(() => {
    (開く)の場合{
      アクティブに設定します(true);
      アニクラス名を設定します('enter');
      タイムアウトを設定する(() => {
        setAniClassName('enter-active');
      });
    } それ以外 {
      アニクラス名を設定します('終了');
      タイムアウトを設定する(() => {
        setAniClassName('exit-active');
      });
    }
  }、 [開ける]);

  if (!open && !active) {
    null を返します。
  }

  ReactDOM.createPortal() を返す
    <div classname="{'modal" '="" +="" aniclassname}="" ontransitionend="{onTransitionEnd}">
      <div classname="modal-content">{子}</div>
      <div classname="modal-close-btn" onclick="{onClose}">
        x
      </div>
    </div>,
    文書本文、
  );
};

アニメーションの流れ工程が実現されており、スタイルも合わせて記述するはずです。たとえば、フェード効果を実現したいとします。

。入力 {
  不透明度: 0;
}
.enter-active {
  遷移: 不透明度 200 ミリ秒、イーズインアウト;
  不透明度: 1;
}
.enter-done {
  不透明度: 1;
}
。出口 {
  不透明度: 1;
}
.exit-active {
  不透明度: 0;
  遷移: 不透明度 200 ミリ秒、イーズインアウト;
}
.終了完了{
  不透明度: 0;
}

ズーム効果を実現したい場合は、これらのクラスを変更するだけです。

アニメーション付きのポップアップウィンドウが実装されました。

方向:

定数App = () => {
  定数[open, setOpen] = useState(false);

  戻る (
    <div クラス名="app">
      <button onclick="{()" ==""> setOpen(true)}>モーダルを表示</button>
      <modal open="{open}" onclose="{()" ==""> setOpen(false)}>
        モーダルコンテンツ
      </モーダル>
    </div>
  );
};

リンクをクリックして、独自の React ポップアップ ウィンドウ デモを実装し、その効果を確認してください。

同様にToastなども存在しますが、これも同様に実装可能です。

3. 反応遷移グループ

動的な効果を実現するために、 react-transition-group の CSSTransition コンポーネントを借用しました。 CSSTransitionは動的な展開と終了のプロセスをカプセル化します。ポップアップ ウィンドウを実装するときに、このコンポーネントを直接使用できます。

ここで重要なプロパティunmountOnExitがあります。これは、アニメーションの終了後にコンポーネントがアンインストールされることを意味します。

const モーダル = ({ open, onClose }) => {
  // http://reactcommunity.org/react-transition-group/css-transition/
  // プロパティは true/false で、true はアニメーションを展開し、false はアニメーションを閉じます。return createPortal(
    <csstransition in="{open}" timeout="{200}" unmountonexit="">
      <div クラス名="モーダル">
        <div classname="modal-content">{子供}</div>
        <div classname="modal-close-btn" onclick="{onClose}">
          x
        </div>
      </div>
    </csstransition>,
    文書本文、
  );
};

CSSTransition コンポーネントを使用すると、Modal のアニメーションがさらに便利になります。

4. 結論

ここまでで、アニメーション化するReact Modalコンポーネントが実装されました。 React には Vue の公式定義に似た<transition>タグはありませんが、自分で実装したり、サードパーティのコンポーネントの助けを借りて実装したりできます。

上記は、React で動的ポップアップ ウィンドウ コンポーネントを実装する方法の詳細です。React ポップアップ ウィンドウ コンポーネントの詳細については、123WORDPRESS.COM の他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • React は antd のアップロード コンポーネントを使用してファイル フォーム送信機能を実装します (完全なコード)
  • React 純粋関数コンポーネント setState がページ更新を更新しない問題の解決方法
  • React 星評価コンポーネントの実装
  • Reactコンポーネントをフルスクリーンにする方法

<<:  show processlist コマンドによる MySQL パフォーマンス検査の説明

>>:  カスタム Docker イメージを作成するための Dockerfile の詳細な説明と CMD と ENTRYPOINT 命令の比較

推薦する

Linuxにおけるumaskコマンドの使用原理と計算方法の詳しい解説

目次umask umaskの使用法原理1. umask値2. ファイルディレクトリの最大権限3. 従...

Vite と Vue CLI の長所と短所

Vue エコシステムには Vite と呼ばれる新しいビルド ツールがあり、Vue CLI よりも 1...

上位Nを見つけるためのMySQLグループソートの詳細な説明

MySQLグループソートで上位Nを見つけるテーブル構造grp でグループ化し、num で並べ替えて、...

HTML img タグの alt 属性と title 属性の使い方の紹介

ブラウザベンダーが標準を曲げて、ルールに従わないことをすると、問題や少なくとも混乱が生じる可能性があ...

Centos7 に PHP と Nginx をインストールする詳細なチュートリアル

Centos のサーバー側への適用がますます普及するにつれて、Centos7 もますます使用されるよ...

複数人チャットルームを実現する js コード

この記事の例では、多人数チャットルームを実装するためのjsコードの具体的なコードを参考までに共有して...

Nginx で IP と IP 範囲をブロックする方法

前面に書かれたNginx は単なるリバース プロキシおよび負荷分散サーバーではなく、電流制限、キャッ...

MySQL インデックスのクイックガイド

MySQL インデックスの確立は、MySQL の効率的な操作にとって非常に重要です。インデックスによ...

コンパイル/サーバーなしでブラウザにCommonJSモジュールを実装する

目次導入1. one-click.jsとは2. パッケージングツールはどのように機能しますか? 3....

HTML テーブルタグチュートリアル (13): 内部境界スタイル属性ルール

RULES を使用すると、テーブルの内部境界のスタイルを制御できます。基本的な構文<TABLE...

シンプルなドラッグ効果を実現するJavaScript

この記事では、ドラッグ効果を実現するためのJavaScriptの具体的なコードを参考までに紹介します...

初心者がHTMLタグを学ぶ(1)

初心者は、いくつかの HTML タグを理解することで HTML を学習できます。この入門書は、初心者...

Dockerデータ管理とネットワーク通信の使用

Docker をインストールし、Docker コアとインストールを通じて簡単な操作を実行できます。 ...

複数の Tomcat を展開して起動し、プロジェクトを移行する方法を 1 つの記事で学習します。

目次tomcatをデプロイする1.ダウンロードして解凍する2. 設定ファイルを変更する移植プロジェク...

MySQL トリガー: トリガーの作成と使用

この記事では、例を使用して MySQL トリガーの作成と使用について説明します。ご参考までに、詳細は...