[解決済み】不要なウィジェットビルドの対処方法は?
質問
様々な理由により、時々
build
メソッドが再度呼び出されます。
親が更新されたために起こることは分かっています。しかし、これは望ましくない効果を引き起こします。
この問題が発生する典型的な場面は
FutureBuilder
このように
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: httpCall(),
builder: (context, snapshot) {
// create some layout here
},
);
}
この例では、もし ビルド メソッドが再び呼び出された場合、別の HTTP リクエストが発生します。これは望ましいことではありません。
このことを考えると、不要なビルドにどう対処すればいいのでしょうか?ビルドの呼び出しを防ぐ方法はないのでしょうか?
解決方法は?
その ビルド メソッドは、そのような設計になっています。 純粋/副作用なし . これは、次のような多くの外的要因が、新しいウィジェット構築の引き金となる可能性があるためです。
- ルートpop/push
- キーボードの表示や向きの変更に伴う画面サイズの変更。
- 親ウィジェットが子ウィジェットを再作成した
-
ウィジェットが依存するInheritedWidget (
Class.of(context)
パターン)変更
これはつまり
build
メソッドは
ない
http 呼び出しのトリガーとなったり、状態を変更したりします。
.
質問との関連は?
あなたが直面している問題は、あなたのビルドメソッドが副作用を持ち、純粋でないため、余計なビルドコールを厄介なものにしていることです。
ビルドコールを防ぐ代わりに、ビルドメソッドを純粋なものにし、いつでも影響を受けずに呼び出せるようにする必要があります。
この例の場合、ウィジェットを
StatefulWidget
への HTTP 呼び出しを抽出し、その HTTP 呼び出しを
initState
の
State
:
class Example extends StatefulWidget {
@override
_ExampleState createState() => _ExampleState();
}
class _ExampleState extends State<Example> {
Future<int> future;
@override
void initState() {
future = Future.value(42);
super.initState();
}
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: future,
builder: (context, snapshot) {
// create some layout here
},
);
}
}
もう分かっているんです。私がここに来たのは 本当に リビルドを最適化したい
また、子ウィジェットも強制的にビルドさせることなく、リビルドが可能なウィジェットを作成することも可能です。
ウィジェットのインスタンスが同じままだと、Flutterは意図的に子ウィジェットをリビルドしないようにします。これは、不要な再構築を防ぐために、Widget Treeの一部をキャッシュできることを意味します。
最も簡単な方法は、dartを使用することです。
const
のコンストラクタを使用します。
@override
Widget build(BuildContext context) {
return const DecoratedBox(
decoration: BoxDecoration(),
child: Text("Hello World"),
);
}
おかげさまで
const
キーワードのインスタンスは
DecoratedBox
は、buildが何百回呼ばれても同じです。
しかし、同じ結果を手動で達成することができます。
@override
Widget build(BuildContext context) {
final subtree = MyWidget(
child: Text("Hello World")
);
return StreamBuilder<String>(
stream: stream,
initialData: "Foo",
builder: (context, snapshot) {
return Column(
children: <Widget>[
Text(snapshot.data),
subtree,
],
);
},
);
}
この例では、StreamBuilderが新しい値を通知されるとき。
subtree
は、StreamBuilder/Columnが再構築されても、再構築されない。
これは、クロージャのおかげで
MyWidget
は変更されていない。
このパターンはアニメーションでよく使われる。典型的な使い方は
AnimatedBuilder
のようなすべてのトランジションと
AlignTransition
.
を格納することもできます。
subtree
をクラスのフィールドに追加することをお勧めします。ただし、ホットリロード機能が壊れてしまうので、あまりお勧めできません。
関連
-
[解決済み] Flutter - くねくね動くアニメーションを作るには?
-
Gradleの失敗 プロジェクト':app'の評価に問題が発生しました。
-
[解決済み] Flutterで丸みを帯びたボタン/border-radius付きボタンを作成する
-
[解決済み] Flutterでウィジェットにボーダーを追加するには?
-
Solve flutter Android ライセンスの状態が不明です。Android SDK Managerを再インストールまたはアップデートしてみてください。
-
[解決済み】flutterのwrap_contentとmatch_parentに相当するもの?
-
[解決済み] Flutter プログラムでアプリを終了させる方法
-
[解決済み] Widgetの高さを取得するには?
-
[解決済み] Flutterアプリのビルド番号とバージョン番号を取得する方法
-
[解決済み] FlutterでtextAlignプロパティはどのような状況で動作しますか?
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Flutter give コンテナ 丸みを帯びたボーダー
-
[解決済み] flutterで文字に下線を引く方法
-
Gradleの失敗 プロジェクト':app'の評価に問題が発生しました。
-
[解決済み] ヌル値に対して使用されるヌルチェック演算子
-
[解決済み】Dartの名前付きパラメータと位置付きパラメータの違いは何ですか?
-
[解決済み】縦型ビューポートの高さが制限されない。
-
[解決済み】flutterはアプバー上の戻るボタンを削除します。
-
[解決済み] Flutter プログラムでアプリを終了させる方法
-
[解決済み] Flutter FirestoreでD8が発生:要求されたクラスを単一のdexファイルに収められない (# methods: 71610 > 65536) in Android Studio
-
[解決済み] FlutterでtextAlignプロパティはどのような状況で動作しますか?