[解決済み] React - 単一のコンポーネントのマウントとアンマウントをアニメーション化する
2022-07-14 02:16:33
質問
こんな簡単なことが簡単にできるはずなのに、あまりの複雑さに身の毛がよだちます。
私がしたいことは、React コンポーネントのマウントとアンマウントをアニメーション化すること、それだけです。私がこれまでに試したことと、各ソリューションが動作しない理由は以下のとおりです。
-
ReactCSSTransitionGroup
- CSSのクラスは全く使っておらず、全てJSのスタイルなので、これではうまくいきません。 -
ReactTransitionGroup
- この低レベルのAPIは素晴らしいのですが、アニメーションが完了したときにコールバックを使用する必要があるので、CSSトランジションを使用するだけではここではうまくいきません。常にアニメーションライブラリがあり、それが次のポイントにつながります。 - GreenSock - ライセンスがビジネスユースには制限されすぎていると思います。
-
React Motion - これは素晴らしいように見えますが
TransitionMotion
は非常にわかりにくく、私が必要とするものに対して過度に複雑です。 -
もちろん、マテリアル UI のように、要素はレンダリングされるが非表示のままにしておくというトリックを行うこともできます (
left: -10000px
) を使用することもできますが、私はそのような方法を取りたくありません。私はそれをハチャメチャだと思っていますし、私は が欲しい コンポーネントをアンマウントして、DOM を散らかさないようにしたいのです。
私は何かが欲しいのです。 簡単 を実装したいです。マウント時に、スタイルのセットをアニメーション化し、アンマウント時に、同じ (または別の) スタイルのセットをアニメーション化します。完了です。また、複数のプラットフォームで高いパフォーマンスを発揮する必要があります。
私はここでレンガの壁にぶつかりました。もし私が何かを見落としていて、これを行う簡単な方法があるのなら教えてください。
どのように解決するのですか?
少し長くなりますが、このアニメーションを実現するために、すべてのネイティブイベントとメソッドを使用しました。いいえ
ReactCSSTransitionGroup
,
ReactTransitionGroup
など。
使ったことのあるもの
- Reactのライフサイクルメソッド
-
onTransitionEnd
イベント
この仕組み
-
渡された mount prop に基づいて要素をマウントする(
mounted
) と、デフォルトのスタイル (opacity: 0
) -
マウントまたはアップデート後に
componentDidMount
(componentWillReceiveProps
をクリックすると、スタイルが変更されます。opacity: 1
) をタイムアウトで変更します (非同期にするため)。 -
アンマウント時に、アンマウントを識別するためのpropをコンポーネントに渡し、再度スタイルを変更する(
opacity: 0
),onTransitionEnd
で、DOMから要素をアンマウントする。
サイクルを継続します。
コードに目を通すと、理解できるはずです。何か説明が必要な場合は、コメントを残してください。
これが役立つことを願っています。
class App extends React.Component{
constructor(props) {
super(props)
this.transitionEnd = this.transitionEnd.bind(this)
this.mountStyle = this.mountStyle.bind(this)
this.unMountStyle = this.unMountStyle.bind(this)
this.state ={ //base css
show: true,
style :{
fontSize: 60,
opacity: 0,
transition: 'all 2s ease',
}
}
}
componentWillReceiveProps(newProps) { // check for the mounted props
if(!newProps.mounted)
return this.unMountStyle() // call outro animation when mounted prop is false
this.setState({ // remount the node when the mounted prop is true
show: true
})
setTimeout(this.mountStyle, 10) // call the into animation
}
unMountStyle() { // css for unmount animation
this.setState({
style: {
fontSize: 60,
opacity: 0,
transition: 'all 1s ease',
}
})
}
mountStyle() { // css for mount animation
this.setState({
style: {
fontSize: 60,
opacity: 1,
transition: 'all 1s ease',
}
})
}
componentDidMount(){
setTimeout(this.mountStyle, 10) // call the into animation
}
transitionEnd(){
if(!this.props.mounted){ // remove the node on transition end when the mounted prop is false
this.setState({
show: false
})
}
}
render() {
return this.state.show && <h1 style={this.state.style} onTransitionEnd={this.transitionEnd}>Hello</h1>
}
}
class Parent extends React.Component{
constructor(props){
super(props)
this.buttonClick = this.buttonClick.bind(this)
this.state = {
showChild: true,
}
}
buttonClick(){
this.setState({
showChild: !this.state.showChild
})
}
render(){
return <div>
<App onTransitionEnd={this.transitionEnd} mounted={this.state.showChild}/>
<button onClick={this.buttonClick}>{this.state.showChild ? 'Unmount': 'Mount'}</button>
</div>
}
}
ReactDOM.render(<Parent />, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.2/react-with-addons.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
関連
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
ハートビート・エフェクトのためのHTML+CSS
-
HTML ホテル フォームによるフィルタリング
-
HTML+cssのボックスモデル例(円、半円など)「border-radius」使いやすい
-
HTMLテーブルのテーブル分割とマージ(colspan, rowspan)
-
ランダム・ネームドロッパーを実装するためのhtmlサンプルコード
-
Html階層型ボックスシャドウ効果サンプルコード
-
QQの一時的なダイアログボックスをポップアップし、友人を追加せずにオンラインで話す効果を達成する方法
-
sublime / vscodeショートカットHTMLコード生成の実装
-
HTMLページを縮小した後にスクロールバーを表示するサンプルコード
-
html のリストボックス、テキストフィールド、ファイルフィールドのコード例