Commit 150ac20

derdilla <82763757+NobodyForNothing@users.noreply.github.com>
2023-10-01 15:42:15
avoid rebuilds in ConsistentFutureBuilder
Signed-off-by: derdilla <82763757+NobodyForNothing@users.noreply.github.com>
1 parent e7e39a4
Changed files (1)
lib/components/consistent_future_builder.dart
@@ -1,7 +1,11 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_gen/gen_l10n/app_localizations.dart';
 
-class ConsistentFutureBuilder<T> extends StatelessWidget {
+class ConsistentFutureBuilder<T> extends StatefulWidget {
+  /// Future that gets evaluated.
+  ///
+  /// This Future is saved as a state, so the build function won't get called again when a rebuild occurs. The future
+  /// gets evaluated once.
   final Future<T> future;
   final Widget Function(BuildContext context, T result) onData;
   
@@ -11,22 +15,35 @@ class ConsistentFutureBuilder<T> extends StatelessWidget {
   
   const ConsistentFutureBuilder({super.key, required this.future, this.onNotStarted, this.onWaiting, this.onError, required this.onData});
 
+  @override
+  State<ConsistentFutureBuilder<T>> createState() => _ConsistentFutureBuilderState<T>();
+}
+
+class _ConsistentFutureBuilderState<T> extends State<ConsistentFutureBuilder<T>> {
+  late final Future<T> _future; // avoid rebuilds
+
+  @override
+  void initState() {
+    super.initState();
+    _future = widget.future;
+  }
+
   @override
   Widget build(BuildContext context) {
     return FutureBuilder<T>(
-      future: future,
+      future: _future,
       builder: (BuildContext context, AsyncSnapshot<T> snapshot) {
         if (snapshot.hasError) {
           return Text(AppLocalizations.of(context)!.error(snapshot.error.toString()));
         }
         switch (snapshot.connectionState) {
           case ConnectionState.none:
-            return onNotStarted ?? Text(AppLocalizations.of(context)!.errNotStarted);
+            return widget.onNotStarted ?? Text(AppLocalizations.of(context)!.errNotStarted);
           case ConnectionState.waiting:
           case ConnectionState.active:
-            return onWaiting ?? Text(AppLocalizations.of(context)!.loading);
+            return widget.onWaiting ?? Text(AppLocalizations.of(context)!.loading);
           case ConnectionState.done:
-            return onData(context, snapshot.data as T);
+            return widget.onData(context, snapshot.data as T);
         }
       });
   }