[解決済み] React Material UI のトランジション コンポーネントを使用して、リストに項目を追加するアニメーションを作成するにはどうすればよいですか?
質問
このようなクラスがあります。
class Demo extends React.Component {
constructor(props) {
super(props);
this.state = {
items: []
};
this.add = this.add.bind(this);
this.clear = this.clear.bind(this);
}
add() {
this.setState(prev => {
const n = prev.items.length;
return {
items: [<li key={n}>Hello, World {n}!</li>, ...prev.items]
};
});
}
clear() {
this.setState({ items: [] });
}
render() {
return (
<div>
<div>
<button onClick={this.add}>Add</button>
<button onClick={this.clear}>Clear</button>
</div>
{/* This is wrong, not sure what to do though... */}
<Collapse in={this.state.items.length > 0}>
<ul>{this.state.items}</ul>
</Collapse>
</div>
);
}
}
サンドボックスのリンクです。 https://codesandbox.io/s/material-demo-ggv04?file=/Demo.js
私は、"add" ボタンをクリックするたびに、新しいアイテムがリストの一番上にアニメーションで存在するようになり、既存のアイテムが下に押し出されるようにしようとしています。しかし、どのように進めればいいのかわかりません。
追加リソース
- 実現したいことの例 https://codeburst.io/yet-another-to-do-list-app-this-time-with-react-transition-group-7d2d1cdf37fd
-
React Transition Group Transitionのドキュメントです。
http://reactcommunity.org/react-transition-group/transition
(が内部で使っているようです)。
Collapse
)
解決方法は?
サンドボックスのコードを更新して、ご希望に沿うようにしましたが、MaterialUIがそのための最適なライブラリとは思えません(もっと良い方法を見逃しているかもしれませんが)。
課題は、新しいアイテムを追加するとき、それがまだDOMに存在しないことです。そして、これらのアニメーションライブラリ/コンポーネントのほとんどは、要素がDOMに存在することを必要とし、それらは単に"hide"と遷移時間と共に"show"を行うだけです。
私も同じような状況でしたが、いろいろ調べた結果、まだ DOM にない要素のアニメーションを扱えるより良いライブラリは フレーマーモーション . (彼らのドキュメントを確認するには マウントアニメーション )
とにかく、以下は、新しい コード・サンドボックス ので、見てみてください。私が行った変更点
ランダムキーの削除
で
map
を使用してリストを作成する関数です。
<Collapse />
コンポーネントで、ランダムな整数を取得し、それを
key
をコンポーネントに追加します。React が適切にふりをするためには一貫したキーが必要なので、この乱数を削除することで "Toggle" ボタンが適切にアニメーションしない問題が修正されました。(アイテムのリストにユニークなIDがない場合は、単に
map
関数は、良い解決策とは言えませんが、乱数よりはましです)。
<Collapse key={i} timeout={this.state.collapseTimeout} in={this.state.open}>
{it}
</Collapse>
トグルを制御するための新機能を追加
ここでのアプローチは、リストにアイテムを追加し、その要素が DOM 内にある後に
<Collapse />
少し待ってからもう一度開いてください(視覚的にアニメーションを見ることができるように)。そのためには、collapse の値を明示的に設定できる新しい "toggle" 関数が必要でした。
toggleValue(value) {
this.setState(() => {
return {
open: value
};
});
}
崩壊時のタイムアウトを可変にしました
最後の問題は
<Collapse />
新しいアイテムが追加されたとき、それを閉じるためのアニメーションがトリガーされていました。この解決策は、折りたたみのタイムアウトを動的に変更することで、そのようなことが起こらないようにしました。
setCollapseTimeout(value) {
this.setState(() => {
return {
collapseTimeout: value
};
});
}
要素をリストに追加するときは、アニメーションを起動するのを待ちます。
ここでも、まだ DOM に入っていない要素に関する問題を回避するために
setTimeout
をトグルするために待機する、あるいは
<Collapse />
. それは、あなたの
add()
関数を使用します。
add() {
this.toggleValue(false);
this.setCollapseTimeout(0);
this.setState(prev => {
const n = prev.items.length;
return {
items: [<li key={n}>Hello, World {n}!</li>, ...prev.items]
};
});
setTimeout(() => {
this.setCollapseTimeout(300);
this.toggleValue(true);
}, 100);
}
を作るという、これまたハチャメチャな解決策。
<Collapse />
のMaterialUIは、まだDOMにない要素で動作します。しかし、前述のように、そのためのより良いライブラリが他にあります。
がんばってください :)
関連
-
[解決済み] Uncaught Invariant Violation: 前のレンダリング中よりも多くのフックをレンダリングした
-
[解決済み] React with ES7: Uncaught TypeError: Cannot read property 'state' of undefined [duplicate] (未定義のプロパティ'state'を読み込むことはできません。
-
[解決済み】SyntaxError: 'import' と 'export' は 'sourceType: module' とだけ表示されるかもしれない - Gulp
-
[解決済み】SyntaxError: 期待された式が、'<'を得た。
-
[解決済み] 配列から特定の項目を削除するにはどうすればよいですか?
-
[解決済み] Reactコンポーネントに条件付きで属性を追加するにはどうすればよいですか?
-
[解決済み] Reactで親の状態を更新するにはどうしたらいいですか?
-
[解決済み] React HooksでcomponentWillMount()を使用するには?
-
[解決済み】ES6クラスベースのReactコンポーネントと機能的なES6 Reactコンポーネントの使い分けはいつ?
-
[解決済み] MakeStyles を使用してコンポーネントのスタイルを設定し、マテリアル UI のライフサイクル メソッドを維持するにはどうすればよいですか?
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】 Uncaught TypeError: data.push is not a function
-
[解決済み】SecurityError: オリジンを持つフレームがクロスオリジンフレームにアクセスするのをブロックした
-
[解決済み】JavaScript "Uncaught TypeError: object is not a function" 連想性の質問
-
[解決済み】「Uncaught TypeError: Chromeで "Illegal invocation "が発生する。
-
[解決済み】未定義のプロパティ 'bind' を読み込めない。React.js【重複あり
-
[解決済み】JavaScriptのボタンonclickが機能しない
-
[解決済み】React-Routerの子が1つしかない。
-
[解決済み】WebSocket接続に失敗しました。WebSocket のハンドシェイク中にエラーが発生しました。予期しない応答コードです。400
-
[解決済み】TypeError:res.jsonは関数ではありません。
-
[解決済み】未定義のプロパティ 'forEach' を読み取ることができない